All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH v3 1/6] docs/zh_TW: update admin-guide
  @ 2023-08-07 12:00  4% ` Hu Haowen
  0 siblings, 0 replies; 200+ results
From: Hu Haowen @ 2023-08-07 12:00 UTC (permalink / raw)
  To: corbet; +Cc: Hu Haowen, linux-doc, linux-kernel

Update zh_TW's admin-guide documentation concentrating on the following
aspects:

    * The file tree structure changes of the main documentation;
    * Some changes and ideas from zh_CN translation;
    * Removal for several obsoleted contents within the zh_TW translation
      or those which are not exising anymore in the main documentation.
    * Replacements for some incorrect words and phrases in traditional
      Chinese or those which are odd within their context being hard for
      readers to comprehend.

Signed-off-by: Hu Haowen <src.res.211@gmail.com>
---
 .../translations/zh_TW/admin-guide/README.rst | 166 ++--
 .../zh_TW/admin-guide/bootconfig.rst          | 294 +++++++
 .../zh_TW/admin-guide/bug-bisect.rst          |  12 +-
 .../zh_TW/admin-guide/bug-hunting.rst         |  40 +-
 .../zh_TW/admin-guide/clearing-warn-once.rst  |   6 +-
 .../zh_TW/admin-guide/cpu-load.rst            |  10 +-
 .../zh_TW/admin-guide/cputopology.rst         |  98 +++
 .../translations/zh_TW/admin-guide/index.rst  | 136 ++--
 .../translations/zh_TW/admin-guide/init.rst   |  38 +-
 .../zh_TW/admin-guide/lockup-watchdogs.rst    |  69 ++
 .../zh_TW/admin-guide/mm/damon/index.rst      |  31 +
 .../zh_TW/admin-guide/mm/damon/lru_sort.rst   | 265 +++++++
 .../zh_TW/admin-guide/mm/damon/reclaim.rst    | 230 ++++++
 .../zh_TW/admin-guide/mm/damon/start.rst      | 126 +++
 .../zh_TW/admin-guide/mm/damon/usage.rst      | 593 ++++++++++++++
 .../zh_TW/admin-guide/mm/index.rst            |  52 ++
 .../translations/zh_TW/admin-guide/mm/ksm.rst | 201 +++++
 .../zh_TW/admin-guide/reporting-issues.rst    | 729 +++++++++---------
 .../admin-guide/reporting-regressions.rst     | 371 +++++++++
 .../zh_TW/admin-guide/security-bugs.rst       |  28 +-
 .../translations/zh_TW/admin-guide/sysrq.rst  | 283 +++++++
 .../zh_TW/admin-guide/tainted-kernels.rst     |  86 +--
 .../zh_TW/admin-guide/unicode.rst             |  12 +-
 23 files changed, 3233 insertions(+), 643 deletions(-)
 create mode 100644 Documentation/translations/zh_TW/admin-guide/bootconfig.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/cputopology.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/index.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/ksm.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/sysrq.rst

diff --git a/Documentation/translations/zh_TW/admin-guide/README.rst b/Documentation/translations/zh_TW/admin-guide/README.rst
index 6ce97edbab37..4cb581f5994a 100644
--- a/Documentation/translations/zh_TW/admin-guide/README.rst
+++ b/Documentation/translations/zh_TW/admin-guide/README.rst
@@ -7,18 +7,18 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
-Linux內核5.x版本 <http://kernel.org/>
+Linux內核6.x版本 <http://kernel.org/>
 =========================================
 
-以下是Linux版本5的發行註記。仔細閱讀它們,
+以下是Linux版本6的發行註記。仔細閱讀它們,
 它們會告訴你這些都是什麼,解釋如何安裝內核,以及遇到問題時該如何做。
 
 什麼是Linux?
 ---------------
 
-  Linux是Unix作業系統的克隆版本,由Linus Torvalds在一個鬆散的網絡黑客
+  Linux是Unix操作系統的克隆版本,由Linus Torvalds在一個鬆散的網絡黑客
   (Hacker,無貶義)團隊的幫助下從頭開始編寫。它旨在實現兼容POSIX和
   單一UNIX規範。
 
@@ -28,7 +28,7 @@ Linux內核5.x版本 <http://kernel.org/>
 
   Linux在GNU通用公共許可證,版本2(GNU GPLv2)下分發,詳見隨附的COPYING文件。
 
-它能在什麼樣的硬體上運行?
+它能在什麼樣的硬件上運行?
 -----------------------------
 
   雖然Linux最初是爲32位的x86 PC機(386或更高版本)開發的,但今天它也能運行在
@@ -40,16 +40,16 @@ Linux內核5.x版本 <http://kernel.org/>
   單元(PMMU)和一個移植的GNU C編譯器(gcc;GNU Compiler Collection,GCC的一
   部分)。Linux也被移植到許多沒有PMMU的體系架構中,儘管功能顯然受到了一定的
   限制。
-  Linux也被移植到了其自己上。現在可以將內核作爲用戶空間應用程式運行——這被
+  Linux也被移植到了其自己上。現在可以將內核作爲用戶空間應用程序運行——這被
   稱爲用戶模式Linux(UML)。
 
 文檔
 -----
-網際網路上和書籍上都有大量的電子文檔,既有Linux專屬文檔,也有與一般UNIX問題相關
+因特網上和書籍上都有大量的電子文檔,既有Linux專屬文檔,也有與一般UNIX問題相關
 的文檔。我建議在任何Linux FTP站點上查找LDP(Linux文檔項目)書籍的文檔子目錄。
 本自述文件並不是關於系統的文檔:有更好的可用資源。
 
- - 網際網路上和書籍上都有大量的(電子)文檔,既有Linux專屬文檔,也有與普通
+ - 因特網上和書籍上都有大量的(電子)文檔,既有Linux專屬文檔,也有與普通
    UNIX問題相關的文檔。我建議在任何有LDP(Linux文檔項目)書籍的Linux FTP
    站點上查找文檔子目錄。本自述文件並不是關於系統的文檔:有更好的可用資源。
 
@@ -58,33 +58,33 @@ Linux內核5.x版本 <http://kernel.org/>
    :ref:`Documentation/process/changes.rst <changes>` 文件,它包含了升級內核
    可能會導致的問題的相關信息。
 
-安裝內核原始碼
+安裝內核源代碼
 ---------------
 
- - 如果您要安裝完整的原始碼,請把內核tar檔案包放在您有權限的目錄中(例如您
+ - 如果您要安裝完整的源代碼,請把內核tar檔案包放在您有權限的目錄中(例如您
    的主目錄)並將其解包::
 
-     xz -cd linux-5.x.tar.xz | tar xvf -
+     xz -cd linux-6.x.tar.xz | tar xvf -
 
-   將「X」替換成最新內核的版本號。
+   將“X”替換成最新內核的版本號。
 
-   【不要】使用 /usr/src/linux 目錄!這裡有一組庫頭文件使用的內核頭文件
+   【不要】使用 /usr/src/linux 目錄!這裏有一組庫頭文件使用的內核頭文件
    (通常是不完整的)。它們應該與庫匹配,而不是被內核的變化搞得一團糟。
 
- - 您還可以通過打補丁在5.x版本之間升級。補丁以xz格式分發。要通過打補丁進行
-   安裝,請獲取所有較新的補丁文件,進入內核原始碼(linux-5.x)的目錄並
+ - 您還可以通過打補丁在6.x版本之間升級。補丁以xz格式分發。要通過打補丁進行
+   安裝,請獲取所有較新的補丁文件,進入內核源代碼(linux-6.x)的目錄並
    執行::
 
-     xz -cd ../patch-5.x.xz | patch -p1
+     xz -cd ../patch-6.x.xz | patch -p1
 
-   請【按順序】替換所有大於當前原始碼樹版本的「x」,這樣就可以了。您可能想要
+   請【按順序】替換所有大於當前源代碼樹版本的“x”,這樣就可以了。您可能想要
    刪除備份文件(文件名類似xxx~ 或 xxx.orig),並確保沒有失敗的補丁(文件名
    類似xxx# 或 xxx.rej)。如果有,不是你就是我犯了錯誤。
 
-   與5.x內核的補丁不同,5.x.y內核(也稱爲穩定版內核)的補丁不是增量的,而是
-   直接應用於基本的5.x內核。例如,如果您的基本內核是5.0,並且希望應用5.0.3
-   補丁,則不應先應用5.0.1和5.0.2的補丁。類似地,如果您運行的是5.0.2內核,
-   並且希望跳轉到5.0.3,那麼在應用5.0.3補丁之前,必須首先撤銷5.0.2補丁
+   與6.x內核的補丁不同,6.x.y內核(也稱爲穩定版內核)的補丁不是增量的,而是
+   直接應用於基本的6.x內核。例如,如果您的基本內核是6.0,並且希望應用6.0.3
+   補丁,則不應先應用6.0.1和6.0.2的補丁。類似地,如果您運行的是6.0.2內核,
+   並且希望跳轉到6.0.3,那麼在應用6.0.3補丁之前,必須首先撤銷6.0.2補丁
    (即patch -R)。更多關於這方面的內容,請閱讀
    :ref:`Documentation/process/applying-patches.rst <applying_patches>` 。
 
@@ -93,7 +93,7 @@ Linux內核5.x版本 <http://kernel.org/>
 
      linux/scripts/patch-kernel linux
 
-   上面命令中的第一個參數是內核原始碼的位置。補丁是在當前目錄應用的,但是
+   上面命令中的第一個參數是內核源代碼的位置。補丁是在當前目錄應用的,但是
    可以將另一個目錄指定爲第二個參數。
 
  - 確保沒有過時的 .o 文件和依賴項::
@@ -101,30 +101,30 @@ Linux內核5.x版本 <http://kernel.org/>
      cd linux
      make mrproper
 
-   現在您應該已經正確安裝了原始碼。
+   現在您應該已經正確安裝了源代碼。
 
-軟體要求
+軟件要求
 ---------
 
-   編譯和運行5.x內核需要各種軟體包的最新版本。請參考
+   編譯和運行6.x內核需要各種軟件包的最新版本。請參考
    :ref:`Documentation/process/changes.rst <changes>`
-   來了解最低版本要求以及如何升級軟體包。請注意,使用過舊版本的這些包可能會
+   來了解最低版本要求以及如何升級軟件包。請注意,使用過舊版本的這些包可能會
    導致很難追蹤的間接錯誤,因此不要以爲在生成或操作過程中出現明顯問題時可以
    只更新包。
 
 爲內核建立目錄
 ---------------
 
-   編譯內核時,默認情況下所有輸出文件都將與內核原始碼放在一起。使用
+   編譯內核時,默認情況下所有輸出文件都將與內核源代碼放在一起。使用
    ``make O=output/dir`` 選項可以爲輸出文件(包括 .config)指定備用位置。
    例如::
 
-     kernel source code: /usr/src/linux-5.x
+     kernel source code: /usr/src/linux-6.x
      build directory:    /home/name/build/kernel
 
    要配置和構建內核,請使用::
 
-     cd /usr/src/linux-5.x
+     cd /usr/src/linux-6.x
      make O=/home/name/build/kernel menuconfig
      make O=/home/name/build/kernel
      sudo make O=/home/name/build/kernel modules_install install
@@ -136,7 +136,7 @@ Linux內核5.x版本 <http://kernel.org/>
 
    即使只升級一個小版本,也不要跳過此步驟。每個版本中都會添加新的配置選項,
    如果配置文件沒有按預定設置,就會出現奇怪的問題。如果您想以最少的工作量
-   將現有配置升級到新版本,請使用 ``makeoldconfig`` ,它只會詢問您新配置
+   將現有配置升級到新版本,請使用 ``make oldconfig`` ,它只會詢問您新配置
    選項的答案。
 
  - 其他配置命令包括::
@@ -164,17 +164,17 @@ Linux內核5.x版本 <http://kernel.org/>
      "make ${PLATFORM}_defconfig"
                         使用arch/$arch/configs/${PLATFORM}_defconfig中
                         的默認選項值創建一個./.config文件。
-                        用「makehelp」來獲取您體系架構中所有可用平台的列表。
+                        用“make help”來獲取您體系架構中所有可用平臺的列表。
 
      "make allyesconfig"
-                        通過儘可能將選項值設置爲「y」,創建一個
+                        通過儘可能將選項值設置爲“y”,創建一個
                         ./.config文件。
 
      "make allmodconfig"
-                        通過儘可能將選項值設置爲「m」,創建一個
+                        通過儘可能將選項值設置爲“m”,創建一個
                         ./.config文件。
 
-     "make allnoconfig" 通過儘可能將選項值設置爲「n」,創建一個
+     "make allnoconfig" 通過儘可能將選項值設置爲“n”,創建一個
                         ./.config文件。
 
      "make randconfig"  通過隨機設置選項值來創建./.config文件。
@@ -182,7 +182,7 @@ Linux內核5.x版本 <http://kernel.org/>
      "make localmodconfig" 基於當前配置和加載的模塊(lsmod)創建配置。禁用
                            已加載的模塊不需要的任何模塊選項。
 
-                           要爲另一台計算機創建localmodconfig,請將該計算機
+                           要爲另一臺計算機創建localmodconfig,請將該計算機
                            的lsmod存儲到一個文件中,並將其作爲lsmod參數傳入。
 
                            此外,通過在參數LMC_KEEP中指定模塊的路徑,可以將
@@ -200,9 +200,10 @@ Linux內核5.x版本 <http://kernel.org/>
      "make localyesconfig" 與localmodconfig類似,只是它會將所有模塊選項轉換
                            爲內置(=y)。你可以同時通過LMC_KEEP保留模塊。
 
-     "make kvmconfig"   爲kvm客體內核支持啓用其他選項。
+     "make kvm_guest.config"
+                        爲kvm客戶機內核支持啓用其他選項。
 
-     "make xenconfig"   爲xen dom0客體內核支持啓用其他選項。
+     "make xen.config"  爲xen dom0客戶機內核支持啓用其他選項。
 
      "make tinyconfig"  配置儘可能小的內核。
 
@@ -218,10 +219,10 @@ Linux內核5.x版本 <http://kernel.org/>
       這種情況下,數學仿真永遠不會被使用。內核會稍微大一點,但不管
       是否有數學協處理器,都可以在不同的機器上工作。
 
-    - 「kernel hacking」配置細節通常會導致更大或更慢的內核(或兩者
+    - “kernel hacking”配置細節通常會導致更大或更慢的內核(或兩者
       兼而有之),甚至可以通過配置一些例程來主動嘗試破壞壞代碼以發現
       內核問題,從而降低內核的穩定性(kmalloc())。因此,您可能應該
-      用於研究「開發」、「實驗」或「調試」特性相關問題。
+      用於研究“開發”、“實驗”或“調試”特性相關問題。
 
 編譯內核
 ---------
@@ -229,10 +230,8 @@ Linux內核5.x版本 <http://kernel.org/>
  - 確保您至少有gcc 5.1可用。
    有關更多信息,請參閱 :ref:`Documentation/process/changes.rst <changes>` 。
 
-   請注意,您仍然可以使用此內核運行a.out用戶程序。
-
  - 執行 ``make`` 來創建壓縮內核映像。如果您安裝了lilo以適配內核makefile,
-   那麼也可以進行 ``makeinstall`` ,但是您可能需要先檢查特定的lilo設置。
+   那麼也可以進行 ``make install`` ,但是您可能需要先檢查特定的lilo設置。
 
    實際安裝必須以root身份執行,但任何正常構建都不需要。
    無須徒然使用root身份。
@@ -242,8 +241,8 @@ Linux內核5.x版本 <http://kernel.org/>
  - 詳細的內核編譯/生成輸出:
 
    通常,內核構建系統在相當安靜的模式下運行(但不是完全安靜)。但是有時您或
-   其他內核開發人員需要看到編譯、連結或其他命令的執行過程。爲此,可使用
-   「verbose(詳細)」構建模式。
+   其他內核開發人員需要看到編譯、鏈接或其他命令的執行過程。爲此,可使用
+   “verbose(詳細)”構建模式。
    向 ``make`` 命令傳遞 ``V=1`` 來實現,例如::
 
      make V=1 all
@@ -255,15 +254,15 @@ Linux內核5.x版本 <http://kernel.org/>
    與工作內核版本號相同的新內核,請在進行 ``make modules_install`` 安裝
    之前備份modules目錄。
 
-   或者,在編譯之前,使用內核配置選項「LOCALVERSION」向常規內核版本附加
-   一個唯一的後綴。LOCALVERSION可以在「General Setup」菜單中設置。
+   或者,在編譯之前,使用內核配置選項“LOCALVERSION”向常規內核版本附加
+   一個唯一的後綴。LOCALVERSION可以在“General Setup”菜單中設置。
 
  - 爲了引導新內核,您需要將內核映像(例如編譯後的
    .../linux/arch/x86/boot/bzImage)複製到常規可引導內核的位置。
 
  - 不再支持在沒有LILO等啓動裝載程序幫助的情況下直接從軟盤引導內核。
 
-   如果從硬碟引導Linux,很可能使用LILO,它使用/etc/lilo.conf文件中
+   如果從硬盤引導Linux,很可能使用LILO,它使用/etc/lilo.conf文件中
    指定的內核映像文件。內核映像文件通常是/vmlinuz、/boot/vmlinuz、
    /bzImage或/boot/bzImage。使用新內核前,請保存舊映像的副本,並複製
    新映像覆蓋舊映像。然後您【必須重新運行LILO】來更新加載映射!否則,
@@ -284,68 +283,13 @@ Linux內核5.x版本 <http://kernel.org/>
 若遇到問題
 -----------
 
- - 如果您發現了一些可能由於內核缺陷所導致的問題,請檢查MAINTAINERS(維護者)
-   文件看看是否有人與令您遇到麻煩的內核部分相關。如果無人在此列出,那麼第二
-   個最好的方案就是把它們發給我(torvalds@linux-foundation.org),也可能發送
-   到任何其他相關的郵件列表或新聞組。
-
- - 在所有的缺陷報告中,【請】告訴我們您在說什麼內核,如何復現問題,以及您的
-   設置是什麼的(使用您的常識)。如果問題是新的,請告訴我;如果問題是舊的,
-   請嘗試告訴我您什麼時候首次注意到它。
-
- - 如果缺陷導致如下消息::
-
-     unable to handle kernel paging request at address C0000010
-     Oops: 0002
-     EIP:   0010:XXXXXXXX
-     eax: xxxxxxxx   ebx: xxxxxxxx   ecx: xxxxxxxx   edx: xxxxxxxx
-     esi: xxxxxxxx   edi: xxxxxxxx   ebp: xxxxxxxx
-     ds: xxxx  es: xxxx  fs: xxxx  gs: xxxx
-     Pid: xx, process nr: xx
-     xx xx xx xx xx xx xx xx xx xx
-
-   或者類似的內核調試信息顯示在屏幕上或在系統日誌里,請【如實】複製它。
-   可能對你來說轉儲(dump)看起來不可理解,但它確實包含可能有助於調試問題的
-   信息。轉儲上方的文本也很重要:它說明了內核轉儲代碼的原因(在上面的示例中,
-   是由於內核指針錯誤)。更多關於如何理解轉儲的信息,請參見
-   Documentation/admin-guide/bug-hunting.rst。
-
- - 如果使用 CONFIG_KALLSYMS 編譯內核,則可以按原樣發送轉儲,否則必須使用
-   ``ksymoops`` 程序來理解轉儲(但通常首選使用CONFIG_KALLSYMS編譯)。
-   此實用程序可從
-   https://www.kernel.org/pub/linux/utils/kernel/ksymoops/ 下載。
-   或者,您可以手動執行轉儲查找:
-
- - 在調試像上面這樣的轉儲時,如果您可以查找EIP值的含義,這將非常有幫助。
-   十六進位值本身對我或其他任何人都沒有太大幫助:它會取決於特定的內核設置。
-   您應該做的是從EIP行獲取十六進位值(忽略 ``0010:`` ),然後在內核名字列表
-   中查找它,以查看哪個內核函數包含有問題的地址。
-
-   要找到內核函數名,您需要找到與顯示症狀的內核相關聯的系統二進位文件。就是
-   文件「linux/vmlinux」。要提取名字列表並將其與內核崩潰中的EIP進行匹配,
-   請執行::
-
-     nm vmlinux | sort | less
-
-   這將爲您提供一個按升序排序的內核地址列表,從中很容易找到包含有問題的地址
-   的函數。請注意,內核調試消息提供的地址不一定與函數地址完全匹配(事實上,
-   這是不可能的),因此您不能只「grep」列表:不過列表將爲您提供每個內核函數
-   的起點,因此通過查找起始地址低於你正在搜索的地址,但後一個函數的高於的
-   函數,你會找到您想要的。實際上,在您的問題報告中加入一些「上下文」可能是
-   一個好主意,給出相關的上下幾行。
-
-   如果您由於某些原因無法完成上述操作(如您使用預編譯的內核映像或類似的映像),
-   請儘可能多地告訴我您的相關設置信息,這會有所幫助。有關詳細信息請閱讀
-   『Documentation/admin-guide/reporting-issues.rst』。
-
- - 或者,您可以在正在運行的內核上使用gdb(只讀的;即不能更改值或設置斷點)。
-   爲此,請首先使用-g編譯內核;適當地編輯arch/x86/Makefile,然後執行 ``make
-   clean`` 。您還需要啓用CONFIG_PROC_FS(通過 ``make config`` )。
-
-   使用新內核重新啓動後,執行 ``gdb vmlinux /proc/kcore`` 。現在可以使用所有
-   普通的gdb命令。查找系統崩潰點的命令是 ``l *0xXXXXXXXX`` (將xxx替換爲EIP
-   值)。
-
-   用gdb無法調試一個當前未運行的內核是由於gdb(錯誤地)忽略了編譯內核的起始
-   偏移量。
+如果您發現了一些可能由於內核缺陷所導致的問題,請參閱:
+Documentation/translations/zh_CN/admin-guide/reporting-issues.rst 。
+
+想要理解內核錯誤報告,請參閱:
+Documentation/translations/zh_CN/admin-guide/bug-hunting.rst 。
+
+更多用GDB調試內核的信息,請參閱:
+Documentation/translations/zh_CN/dev-tools/gdb-kernel-debugging.rst
+和 Documentation/dev-tools/kgdb.rst 。
 
diff --git a/Documentation/translations/zh_TW/admin-guide/bootconfig.rst b/Documentation/translations/zh_TW/admin-guide/bootconfig.rst
new file mode 100644
index 000000000000..abac5aa60f67
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/bootconfig.rst
@@ -0,0 +1,294 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/bootconfig.rst
+
+:譯者: 吳想成 Wu XiangCheng <bobwxc@email.cn>
+
+========
+引導配置
+========
+
+:作者: Masami Hiramatsu <mhiramat@kernel.org>
+
+概述
+====
+
+引導配置擴展了現有的內核命令行,以一種更有效率的方式在引導內核時進一步支持
+鍵值數據。這允許管理員傳遞一份結構化關鍵字的配置文件。
+
+配置文件語法
+============
+
+引導配置文件的語法採用非常簡單的鍵值結構。每個關鍵字由點連接的單詞組成,鍵
+和值由 ``=`` 連接。值以分號( ``;`` )或換行符( ``\n`` )結尾。數組值中每
+個元素由逗號( ``,`` )分隔。::
+
+  KEY[.WORD[...]] = VALUE[, VALUE2[...]][;]
+
+與內核命令行語法不同,逗號和 ``=`` 周圍允許有空格。
+
+關鍵字只允許包含字母、數字、連字符( ``-`` )和下劃線( ``_`` )。值可包含
+可打印字符和空格,但分號( ``;`` )、換行符( ``\n`` )、逗號( ``,`` )、
+井號( ``#`` )和右大括號( ``}`` )等分隔符除外。
+
+如果你需要在值中使用這些分隔符,可以用雙引號( ``"VALUE"`` )或單引號
+( ``'VALUE'`` )括起來。注意,引號無法轉義。
+
+鍵的值可以爲空或不存在。這些鍵用於檢查該鍵是否存在(類似布爾值)。
+
+鍵值語法
+--------
+
+引導配置文件語法允許用戶通過大括號合併鍵名部分相同的關鍵字。例如::
+
+ foo.bar.baz = value1
+ foo.bar.qux.quux = value2
+
+也可以寫成::
+
+ foo.bar {
+    baz = value1
+    qux.quux = value2
+ }
+
+或者更緊湊一些,寫成::
+
+ foo.bar { baz = value1; qux.quux = value2 }
+
+在這兩種樣式中,引導解析時相同的關鍵字都會自動合併。因此可以追加類似的樹或
+鍵值。
+
+相同關鍵字的值
+--------------
+
+禁止兩個或多個值或數組共享同一個關鍵字。例如::
+
+ foo = bar, baz
+ foo = qux  # !錯誤! 我們不可以重定義相同的關鍵字
+
+如果你想要更新值,必須顯式使用覆蓋操作符 ``:=`` 。例如::
+
+ foo = bar, baz
+ foo := qux
+
+這樣 ``foo`` 關鍵字的值就變成了 ``qux`` 。這對於通過添加(部分)自定義引導
+配置來覆蓋默認值非常有用,免於解析默認引導配置。
+
+如果你想對現有關鍵字追加值作爲數組成員,可以使用 ``+=`` 操作符。例如::
+
+ foo = bar, baz
+ foo += qux
+
+這樣, ``foo`` 關鍵字就同時擁有了 ``bar`` , ``baz`` 和 ``qux`` 。
+
+此外,父關鍵字下可同時存在值和子關鍵字。
+例如,下列配置是可行的。::
+
+ foo = value1
+ foo.bar = value2
+ foo := value3 # 這會更新foo的值。
+
+注意,裸值不能直接放進結構化關鍵字中,必須在大括號外定義它。例如::
+
+ foo {
+     bar = value1
+     bar {
+         baz = value2
+         qux = value3
+     }
+ }
+
+同時,關鍵字下值節點的順序是固定的。如果值和子關鍵字同時存在,值永遠是該關
+鍵字的第一個子節點。因此如果用戶先指定子關鍵字,如::
+
+ foo.bar = value1
+ foo = value2
+
+則在程序(和/proc/bootconfig)中,它會按如下顯示::
+
+ foo = value2
+ foo.bar = value1
+
+註釋
+----
+
+配置語法接受shell腳本風格的註釋。註釋以井號( ``#`` )開始,到換行符
+( ``\n`` )結束。
+
+::
+
+ # comment line
+ foo = value # value is set to foo.
+ bar = 1, # 1st element
+       2, # 2nd element
+       3  # 3rd element
+
+會被解析爲::
+
+ foo = value
+ bar = 1, 2, 3
+
+注意你不能把註釋放在值和分隔符( ``,`` 或 ``;`` )之間。如下配置語法是錯誤的::
+
+ key = 1 # comment
+       ,2
+
+
+/proc/bootconfig
+================
+
+/proc/bootconfig是引導配置的用戶空間接口。與/proc/cmdline不同,此文件內容以
+鍵值列表樣式顯示。
+每個鍵值對一行,樣式如下::
+
+ KEY[.WORDS...] = "[VALUE]"[,"VALUE2"...]
+
+
+用引導配置引導內核
+==================
+
+用引導配置引導內核有兩種方法:將引導配置附加到initrd鏡像或直接嵌入內核中。
+
+*initrd: initial RAM disk,初始內存磁盤*
+
+將引導配置附加到initrd
+----------------------
+
+由於默認情況下引導配置文件是用initrd加載的,因此它將被添加到initrd(initramfs)
+鏡像文件的末尾,其中包含填充、大小、校驗值和12字節幻數,如下所示::
+
+ [initrd][bootconfig][padding][size(le32)][checksum(le32)][#BOOTCONFIG\n]
+
+大小和校驗值爲小端序存放的32位無符號值。
+
+當引導配置被加到initrd鏡像時,整個文件大小會對齊到4字節。空字符( ``\0`` )
+會填補對齊空隙。因此 ``size`` 就是引導配置文件的長度+填充的字節。
+
+Linux內核在內存中解碼initrd鏡像的最後部分以獲取引導配置數據。由於這種“揹負式”
+的方法,只要引導加載器傳遞了正確的initrd文件大小,就無需更改或更新引導加載器
+和內核鏡像本身。如果引導加載器意外傳遞了更長的大小,內核將無法找到引導配置數
+據。
+
+Linux內核在tools/bootconfig下提供了 ``bootconfig`` 命令來完成此操作,管理員
+可以用它從initrd鏡像中刪除或追加配置文件。你可以用以下命令來構建它::
+
+ # make -C tools/bootconfig
+
+要向initrd鏡像添加你的引導配置文件,請按如下命令操作(舊數據會自動移除)::
+
+ # tools/bootconfig/bootconfig -a your-config /boot/initrd.img-X.Y.Z
+
+要從鏡像中移除配置,可以使用-d選項::
+
+ # tools/bootconfig/bootconfig -d /boot/initrd.img-X.Y.Z
+
+然後在內核命令行上添加 ``bootconfig`` 告訴內核去initrd文件末尾尋找內核配置。
+
+將引導配置嵌入內核
+------------------
+
+如果你不能使用initrd,也可以通過Kconfig選項將引導配置文件嵌入內核中。在此情
+況下,你需要用以下選項重新編譯內核::
+
+ CONFIG_BOOT_CONFIG_EMBED=y
+ CONFIG_BOOT_CONFIG_EMBED_FILE="/引導配置/文件/的/路徑"
+
+``CONFIG_BOOT_CONFIG_EMBED_FILE`` 需要從源碼樹或對象樹開始的引導配置文件的
+絕對/相對路徑。內核會將其嵌入作爲默認引導配置。
+
+與將引導配置附加到initrd一樣,你也需要在內核命令行上添加 ``bootconfig`` 告訴
+內核去啓用內嵌的引導配置。
+
+注意,即使你已經設置了此選項,仍可用附加到initrd的其他引導配置覆蓋內嵌的引導
+配置。
+
+通過引導配置傳遞內核參數
+========================
+
+除了內核命令行,引導配置也可以用於傳遞內核參數。所有 ``kernel`` 關鍵字下的鍵
+值對都將直接傳遞給內核命令行。此外, ``init`` 下的鍵值對將通過命令行傳遞給
+init進程。參數按以下順序與用戶給定的內核命令行字符串相連,因此命令行參數可以
+覆蓋引導配置參數(這取決於子系統如何處理參數,但通常前面的參數將被後面的參數
+覆蓋)::
+
+ [bootconfig params][cmdline params] -- [bootconfig init params][cmdline init params]
+
+如果引導配置文件給出的kernel/init參數是::
+
+ kernel {
+   root = 01234567-89ab-cdef-0123-456789abcd
+ }
+ init {
+  splash
+ }
+
+這將被複制到內核命令行字符串中,如下所示::
+
+ root="01234567-89ab-cdef-0123-456789abcd" -- splash
+
+如果用戶給出的其他命令行是::
+
+ ro bootconfig -- quiet
+
+則最後的內核命令行如下::
+
+ root="01234567-89ab-cdef-0123-456789abcd" ro bootconfig -- splash quiet
+
+
+配置文件的限制
+==============
+
+當前最大的配置大小是32KB,關鍵字總數(不是鍵值條目)必須少於1024個節點。
+注意:這不是條目數而是節點數,條目必須消耗超過2個節點(一個關鍵字和一個值)。
+所以從理論上講最多512個鍵值對。如果關鍵字平均包含3個單詞,則可有256個鍵值對。
+在大多數情況下,配置項的數量將少於100個條目,小於8KB,因此這應該足夠了。如果
+節點數超過1024,解析器將返回錯誤,即使文件大小小於32KB。(請注意,此最大尺寸
+不包括填充的空字符。)
+無論如何,因爲 ``bootconfig`` 命令在附加啓動配置到initrd映像時會驗證它,用戶
+可以在引導之前注意到它。
+
+
+引導配置API
+===========
+
+用戶可以查詢或遍歷鍵值對,也可以查找(前綴)根關鍵字節點,並在查找該節點下的
+鍵值。
+
+如果您有一個關鍵字字符串,則可以直接使用 xbc_find_value() 查詢該鍵的值。如果
+你想知道引導配置裏有哪些關鍵字,可以使用 xbc_for_each_key_value() 迭代鍵值對。
+請注意,您需要使用 xbc_array_for_each_value() 訪問數組的值,例如::
+
+ vnode = NULL;
+ xbc_find_value("key.word", &vnode);
+ if (vnode && xbc_node_is_array(vnode))
+    xbc_array_for_each_value(vnode, value) {
+      printk("%s ", value);
+    }
+
+如果您想查找具有前綴字符串的鍵,可以使用 xbc_find_node() 通過前綴字符串查找
+節點,然後用 xbc_node_for_each_key_value() 迭代前綴節點下的鍵。
+
+但最典型的用法是獲取前綴下的命名值或前綴下的命名數組,例如::
+
+ root = xbc_find_node("key.prefix");
+ value = xbc_node_find_value(root, "option", &vnode);
+ ...
+ xbc_node_for_each_array_value(root, "array-option", value, anode) {
+    ...
+ }
+
+這將訪問值“key.prefix.option”的值和“key.prefix.array-option”的數組。
+
+鎖是不需要的,因爲在初始化之後配置只讀。如果需要修改,必須複製所有數據和關鍵字。
+
+
+函數與結構體
+============
+
+相關定義的kernel-doc參見:
+
+ - include/linux/bootconfig.h
+ - lib/bootconfig.c
+
diff --git a/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst b/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst
index 41a39aebb8d6..3f10a9f8f223 100644
--- a/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst
+++ b/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst
@@ -7,7 +7,7 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 二分(bisect)缺陷
 +++++++++++++++++++
@@ -17,14 +17,14 @@
 引言
 =====
 
-始終嘗試由來自kernel.org的原始碼構建的最新內核。如果您沒有信心這樣做,請將
+始終嘗試由來自kernel.org的源代碼構建的最新內核。如果您沒有信心這樣做,請將
 錯誤報告給您的發行版供應商,而不是內核開發人員。
 
 找到缺陷(bug)並不總是那麼容易,不過仍然得去找。如果你找不到它,不要放棄。
-儘可能多的向相關維護人員報告您發現的信息。請參閱MAINTAINERS文件以了解您所
+儘可能多的向相關維護人員報告您發現的信息。請參閱MAINTAINERS文件以瞭解您所
 關注的子系統的維護人員。
 
-在提交錯誤報告之前,請閱讀「Documentation/admin-guide/reporting-issues.rst」。
+在提交錯誤報告之前,請閱讀“Documentation/admin-guide/reporting-issues.rst”。
 
 設備未出現(Devices not appearing)
 ====================================
@@ -38,7 +38,7 @@
 
 操作步驟:
 
-- 從git原始碼構建內核
+- 從git源代碼構建內核
 - 以此開始二分 [#f1]_::
 
 	$ git bisect start
@@ -76,7 +76,7 @@
 如需進一步參考,請閱讀:
 
 - ``git-bisect`` 的手冊頁
-- `Fighting regressions with git bisect(用git bisect解決回歸)
+- `Fighting regressions with git bisect(用git bisect解決迴歸)
   <https://www.kernel.org/pub/software/scm/git/docs/git-bisect-lk2009.html>`_
 - `Fully automated bisecting with "git bisect run"(使用git bisect run
   來全自動二分) <https://lwn.net/Articles/317154>`_
diff --git a/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst b/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst
index 4d813aec77d2..631fd2650929 100644
--- a/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst
+++ b/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst
@@ -7,7 +7,7 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 追蹤缺陷
 =========
@@ -48,8 +48,8 @@
 	 [<c1549f43>] ? sysenter_past_esp+0x40/0x6a
 	---[ end trace 6ebc60ef3981792f ]---
 
-這樣的堆棧跟蹤提供了足夠的信息來識別內核原始碼中發生錯誤的那一行。根據問題的
-嚴重性,它還可能包含 **「Oops」** 一詞,比如::
+這樣的堆棧跟蹤提供了足夠的信息來識別內核源代碼中發生錯誤的那一行。根據問題的
+嚴重性,它還可能包含 **“Oops”** 一詞,比如::
 
 	BUG: unable to handle kernel NULL pointer dereference at   (null)
 	IP: [<c06969d4>] iret_exc+0x7d0/0xa59
@@ -58,17 +58,17 @@
 	...
 
 儘管有 **Oops** 或其他類型的堆棧跟蹤,但通常需要找到出問題的行來識別和處理缺
-陷。在本章中,我們將參考「Oops」來了解需要分析的各種堆棧跟蹤。
+陷。在本章中,我們將參考“Oops”來了解需要分析的各種堆棧跟蹤。
 
 如果內核是用 ``CONFIG_DEBUG_INFO`` 編譯的,那麼可以使用文件:
 `scripts/decode_stacktrace.sh` 。
 
-連結的模塊
+鏈接的模塊
 -----------
 
-受到汙染或正在加載/卸載的模塊用「(…)」標記,汙染標誌在
-`Documentation/admin-guide/tainted-kernels.rst` 文件中進行了描述,「正在被加
-載」用「+」標註,「正在被卸載」用「-」標註。
+受到污染或正在加載/卸載的模塊用“(…)”標記,污染標誌在
+`Documentation/admin-guide/tainted-kernels.rst` 文件中進行了描述,“正在被加
+載”用“+”標註,“正在被卸載”用“-”標註。
 
 
 Oops消息在哪?
@@ -81,19 +81,19 @@ syslog文件,通常是 ``/var/log/messages`` (取決於 ``/etc/syslog.conf``
 
 有時 ``klogd`` 會掛掉,這種情況下您可以運行 ``dmesg > file`` 從內核緩衝區
 讀取數據並保存它。或者您可以 ``cat /proc/kmsg > file`` ,但是您必須適時
-中斷以停止傳輸,因爲 ``kmsg`` 是一個「永無止境的文件」。
+中斷以停止傳輸,因爲 ``kmsg`` 是一個“永無止境的文件”。
 
-如果機器嚴重崩潰,無法輸入命令或磁碟不可用,那還有三個選項:
+如果機器嚴重崩潰,無法輸入命令或磁盤不可用,那還有三個選項:
 
 (1) 手動複製屏幕上的文本,並在機器重新啓動後輸入。很難受,但這是突然崩潰下
-    唯一的選擇。或者你可以用數位相機拍下屏幕——雖然不那麼好,但總比什麼都沒
-    有好。如果消息滾動超出控制台頂部,使用更高解析度(例如 ``vga=791`` )
-    引導啓動將允許您閱讀更多文本。(警告:這需要 ``vesafb`` ,因此對「早期」
+    唯一的選擇。或者你可以用數碼相機拍下屏幕——雖然不那麼好,但總比什麼都沒
+    有好。如果消息滾動超出控制檯頂部,使用更高分辨率(例如 ``vga=791`` )
+    引導啓動將允許您閱讀更多文本。(警告:這需要 ``vesafb`` ,因此對“早期”
     的Oppses沒有幫助)
 
 (2) 從串口終端啓動(參見
     :ref:`Documentation/admin-guide/serial-console.rst <serial_console>` ),
-    在另一台機器上運行數據機然後用你喜歡的通信程序捕獲輸出。
+    在另一臺機器上運行調制解調器然後用你喜歡的通信程序捕獲輸出。
     Minicom運行良好。
 
 (3) 使用Kdump(參閱 Documentation/admin-guide/kdump/kdump.rst ),使用
@@ -103,7 +103,7 @@ syslog文件,通常是 ``/var/log/messages`` (取決於 ``/etc/syslog.conf``
 找到缺陷位置
 -------------
 
-如果你能指出缺陷在內核原始碼中的位置,則報告缺陷的效果會非常好。這有兩種方法。
+如果你能指出缺陷在內核源代碼中的位置,則報告缺陷的效果會非常好。這有兩種方法。
 通常來說使用 ``gdb`` 會比較容易,不過內核需要用調試信息來預編譯。
 
 gdb
@@ -187,7 +187,7 @@ GNU 調試器(GNU debugger, ``gdb`` )是從 ``vmlinux`` 文件中找出OOP
 objdump
 ^^^^^^^^
 
-要調試內核,請使用objdump並從崩潰輸出中查找十六進位偏移,以找到有效的代碼/匯
+要調試內核,請使用objdump並從崩潰輸出中查找十六進制偏移,以找到有效的代碼/匯
 編行。如果沒有調試符號,您將看到所示例程的彙編程序代碼,但是如果內核有調試
 符號,C代碼也將可見(調試符號可以在內核配置菜單的hacking項中啓用)。例如::
 
@@ -197,7 +197,7 @@ objdump
 
    您需要處於內核樹的頂層以便此獲得您的C文件。
 
-如果您無法訪問原始碼,仍然可以使用以下方法調試一些崩潰轉儲(如Dave Miller的
+如果您無法訪問源代碼,仍然可以使用以下方法調試一些崩潰轉儲(如Dave Miller的
 示例崩潰轉儲輸出所示)::
 
      EIP is at 	+0x14/0x4c0
@@ -234,9 +234,9 @@ objdump
 報告缺陷
 ---------
 
-一旦你通過定位缺陷找到了其發生的地方,你可以嘗試自己修復它或者向上游報告它。
+一旦你通過定位缺陷找到了其發生的地方,你可以嘗試自己修復它或者向上遊報告它。
 
-爲了向上游報告,您應該找出用於開發受影響代碼的郵件列表。這可以使用 ``get_maintainer.pl`` 。
+爲了向上遊報告,您應該找出用於開發受影響代碼的郵件列表。這可以使用 ``get_maintainer.pl`` 。
 
 
 例如,您在gspca的sonixj.c文件中發現一個缺陷,則可以通過以下方法找到它的維護者::
@@ -251,7 +251,7 @@ objdump
 
 請注意它將指出:
 
-- 最後接觸原始碼的開發人員(如果這是在git樹中完成的)。在上面的例子中是Tejun
+- 最後接觸源代碼的開發人員(如果這是在git樹中完成的)。在上面的例子中是Tejun
   和Bhaktipriya(在這個特定的案例中,沒有人真正參與這個文件的開發);
 - 驅動維護人員(Hans Verkuil);
 - 子系統維護人員(Mauro Carvalho Chehab);
diff --git a/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst b/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst
index bdc1a22046cf..6961006b4a2d 100644
--- a/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst
+++ b/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst
@@ -2,15 +2,15 @@
 
 .. include:: ../disclaimer-zh_TW.rst
 
-:Translator: 胡皓文 Hu Haowen <src.res@email.cn>
+:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 清除 WARN_ONCE
 --------------
 
-WARN_ONCE / WARN_ON_ONCE / printk_once 僅僅列印一次消息.
+WARN_ONCE / WARN_ON_ONCE / printk_once 僅僅打印一次消息.
 
 echo 1 > /sys/kernel/debug/clear_warn_once
 
-可以清除這種狀態並且再次允許列印一次告警信息,這對於運行測試集後重現問題
+可以清除這種狀態並且再次允許打印一次告警信息,這對於運行測試集後重現問題
 很有用。
 
diff --git a/Documentation/translations/zh_TW/admin-guide/cpu-load.rst b/Documentation/translations/zh_TW/admin-guide/cpu-load.rst
index be087cef1967..cc046f3b7ffa 100644
--- a/Documentation/translations/zh_TW/admin-guide/cpu-load.rst
+++ b/Documentation/translations/zh_TW/admin-guide/cpu-load.rst
@@ -2,7 +2,7 @@
 
 .. include:: ../disclaimer-zh_TW.rst
 
-:Translator: 胡皓文 Hu Haowen <src.res@email.cn>
+:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 ========
 CPU 負載
@@ -20,13 +20,13 @@ Linux通過``/proc/stat``和``/proc/uptime``導出各種信息,用戶空間工
 
     ...
 
-這裡系統認爲在默認採樣周期內有10.01%的時間工作在用戶空間,2.92%的時
+這裏系統認爲在默認採樣週期內有10.01%的時間工作在用戶空間,2.92%的時
 間用在系統空間,總體上有81.63%的時間是空閒的。
 
 大多數情況下``/proc/stat``的信息幾乎真實反映了系統信息,然而,由於內
 核採集這些數據的方式/時間的特點,有時這些信息根本不可靠。
 
-那麼這些信息是如何被搜集的呢?每當時間中斷觸發時,內核查看此刻運行的
+那麼這些信息是如何被蒐集的呢?每當時間中斷觸發時,內核查看此刻運行的
 進程類型,並增加與此類型/狀態進程對應的計數器的值。這種方法的問題是
 在兩次時間中斷之間系統(進程)能夠在多種狀態之間切換多次,而計數器只
 增加最後一種狀態下的計數。
@@ -34,7 +34,7 @@ Linux通過``/proc/stat``和``/proc/uptime``導出各種信息,用戶空間工
 舉例
 ---
 
-假設系統有一個進程以如下方式周期性地占用cpu::
+假設系統有一個進程以如下方式週期性地佔用cpu::
 
      兩個時鐘中斷之間的時間線
     |-----------------------|
@@ -46,7 +46,7 @@ Linux通過``/proc/stat``和``/proc/uptime``導出各種信息,用戶空間工
 在上面的情況下,根據``/proc/stat``的信息(由於當系統處於空閒狀態時,
 時間中斷經常會發生)系統的負載將會是0
 
-大家能夠想像內核的這種行爲會發生在許多情況下,這將導致``/proc/stat``
+大家能夠想象內核的這種行爲會發生在許多情況下,這將導致``/proc/stat``
 中存在相當古怪的信息::
 
 	/* gcc -o hog smallhog.c */
diff --git a/Documentation/translations/zh_TW/admin-guide/cputopology.rst b/Documentation/translations/zh_TW/admin-guide/cputopology.rst
new file mode 100644
index 000000000000..147a286e517c
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/cputopology.rst
@@ -0,0 +1,98 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/cputopology.rst
+
+:翻譯:
+
+  唐藝舟 Tang Yizhou <tangyeechou@gmail.com>
+
+==========================
+如何通過sysfs將CPU拓撲導出
+==========================
+
+CPU拓撲信息通過sysfs導出。顯示的項(屬性)和某些架構的/proc/cpuinfo輸出相似。它們位於
+/sys/devices/system/cpu/cpuX/topology/。請閱讀ABI文件:
+Documentation/ABI/stable/sysfs-devices-system-cpu。
+
+drivers/base/topology.c是體系結構中性的,它導出了這些屬性。然而,die、cluster、book、
+draw這些層次結構相關的文件僅在體系結構提供了下文描述的宏的條件下被創建。
+
+對於支持這個特性的體系結構,它必須在include/asm-XXX/topology.h中定義這些宏中的一部分::
+
+	#define topology_physical_package_id(cpu)
+	#define topology_die_id(cpu)
+	#define topology_cluster_id(cpu)
+	#define topology_core_id(cpu)
+	#define topology_book_id(cpu)
+	#define topology_drawer_id(cpu)
+	#define topology_sibling_cpumask(cpu)
+	#define topology_core_cpumask(cpu)
+	#define topology_cluster_cpumask(cpu)
+	#define topology_die_cpumask(cpu)
+	#define topology_book_cpumask(cpu)
+	#define topology_drawer_cpumask(cpu)
+
+``**_id macros`` 的類型是int。
+``**_cpumask macros`` 的類型是 ``(const) struct cpumask *`` 。後者和恰當的
+``**_siblings`` sysfs屬性對應(除了topology_sibling_cpumask(),它和thread_siblings
+對應)。
+
+爲了在所有體系結構上保持一致,include/linux/topology.h提供了上述所有宏的默認定義,以防
+它們未在include/asm-XXX/topology.h中定義:
+
+1) topology_physical_package_id: -1
+2) topology_die_id: -1
+3) topology_cluster_id: -1
+4) topology_core_id: 0
+5) topology_book_id: -1
+6) topology_drawer_id: -1
+7) topology_sibling_cpumask: 僅入參CPU
+8) topology_core_cpumask: 僅入參CPU
+9) topology_cluster_cpumask: 僅入參CPU
+10) topology_die_cpumask: 僅入參CPU
+11) topology_book_cpumask:  僅入參CPU
+12) topology_drawer_cpumask: 僅入參CPU
+
+此外,CPU拓撲信息由/sys/devices/system/cpu提供,包含下述文件。輸出對應的內部數據源放在
+方括號("[]")中。
+
+    =========== ==================================================================
+    kernel_max: 內核配置允許的最大CPU下標值。[NR_CPUS-1]
+
+    offline:    由於熱插拔移除或者超過內核允許的CPU上限(上文描述的kernel_max)
+                導致未上線的CPU。[~cpu_online_mask + cpus >= NR_CPUS]
+
+    online:     在線的CPU,可供調度使用。[cpu_online_mask]
+
+    possible:   已被分配資源的CPU,如果它們CPU實際存在,可以上線。
+                [cpu_possible_mask]
+
+    present:    被系統識別實際存在的CPU。[cpu_present_mask]
+    =========== ==================================================================
+
+上述輸出的格式和cpulist_parse()兼容[參見 <linux/cpumask.h>]。下面給些例子。
+
+在本例中,系統中有64個CPU,但是CPU 32-63超過了kernel_max值,因爲NR_CPUS配置項是32,
+取值範圍被限制爲0..31。此外注意CPU2和4-31未上線,但是可以上線,因爲它們同時存在於
+present和possible::
+
+     kernel_max: 31
+        offline: 2,4-31,32-63
+         online: 0-1,3
+       possible: 0-31
+        present: 0-31
+
+在本例中,NR_CPUS配置項是128,但內核啓動時設置possible_cpus=144。系統中有4個CPU,
+CPU2被手動設置下線(也是唯一一個可以上線的CPU)::
+
+     kernel_max: 127
+        offline: 2,4-127,128-143
+         online: 0-1,3
+       possible: 0-127
+        present: 0-3
+
+閱讀Documentation/core-api/cpu_hotplug.rst可瞭解開機參數possible_cpus=NUM,同時還
+可以瞭解各種cpumask的信息。
+
diff --git a/Documentation/translations/zh_TW/admin-guide/index.rst b/Documentation/translations/zh_TW/admin-guide/index.rst
index 293c20245783..b51ddf760c4d 100644
--- a/Documentation/translations/zh_TW/admin-guide/index.rst
+++ b/Documentation/translations/zh_TW/admin-guide/index.rst
@@ -3,13 +3,13 @@
 .. include:: ../disclaimer-zh_TW.rst
 
 :Original: :doc:`../../../admin-guide/index`
-:Translator: 胡皓文 Hu Haowen <src.res@email.cn>
+:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 Linux 內核用戶和管理員指南
 ==========================
 
 下面是一組隨時間添加到內核中的面向用戶的文檔的集合。到目前爲止,還沒有一個
-整體的順序或組織 - 這些材料不是一個單一的,連貫的文件!幸運的話,情況會隨著
+整體的順序或組織 - 這些材料不是一個單一的,連貫的文件!幸運的話,情況會隨着
 時間的推移而迅速改善。
 
 這個初始部分包含總體信息,包括描述內核的README, 關於內核參數的文檔等。
@@ -21,15 +21,15 @@ Linux 內核用戶和管理員指南
 
 Todolist:
 
-   kernel-parameters
-   devices
-   sysctl/index
+*   kernel-parameters
+*   devices
+*   sysctl/index
 
 本節介紹CPU漏洞及其緩解措施。
 
 Todolist:
 
-   hw-vuln/index
+*   hw-vuln/index
 
 下面的一組文檔,針對的是試圖跟蹤問題和bug的用戶。
 
@@ -37,6 +37,7 @@ Todolist:
    :maxdepth: 1
 
    reporting-issues
+   reporting-regressions
    security-bugs
    bug-hunting
    bug-bisect
@@ -45,18 +46,17 @@ Todolist:
 
 Todolist:
 
-   reporting-bugs
-   ramoops
-   dynamic-debug-howto
-   kdump/index
-   perf/index
+*   ramoops
+*   dynamic-debug-howto
+*   kdump/index
+*   perf/index
 
-這是應用程式開發人員感興趣的章節的開始。可以在這裡找到涵蓋內核ABI各個
+這是應用程序開發人員感興趣的章節的開始。可以在這裏找到涵蓋內核ABI各個
 方面的文檔。
 
 Todolist:
 
-   sysfs-rules
+*   sysfs-rules
 
 本手冊的其餘部分包括各種指南,介紹如何根據您的喜好配置內核的特定行爲。
 
@@ -64,67 +64,67 @@ Todolist:
 .. toctree::
    :maxdepth: 1
 
+   bootconfig
    clearing-warn-once
    cpu-load
+   cputopology
+   lockup-watchdogs
    unicode
+   sysrq
+   mm/index
 
 Todolist:
 
-   acpi/index
-   aoe/index
-   auxdisplay/index
-   bcache
-   binderfs
-   binfmt-misc
-   blockdev/index
-   bootconfig
-   braille-console
-   btmrvl
-   cgroup-v1/index
-   cgroup-v2
-   cifs/index
-   cputopology
-   dell_rbu
-   device-mapper/index
-   edid
-   efi-stub
-   ext4
-   nfs/index
-   gpio/index
-   highuid
-   hw_random
-   initrd
-   iostats
-   java
-   jfs
-   kernel-per-CPU-kthreads
-   laptops/index
-   lcd-panel-cgram
-   ldm
-   lockup-watchdogs
-   LSM/index
-   md
-   media/index
-   mm/index
-   module-signing
-   mono
-   namespaces/index
-   numastat
-   parport
-   perf-security
-   pm/index
-   pnp
-   rapidio
-   ras
-   rtc
-   serial-console
-   svga
-   sysrq
-   thunderbolt
-   ufs
-   vga-softcursor
-   video-output
-   xfs
+*   acpi/index
+*   aoe/index
+*   auxdisplay/index
+*   bcache
+*   binderfs
+*   binfmt-misc
+*   blockdev/index
+*   braille-console
+*   btmrvl
+*   cgroup-v1/index
+*   cgroup-v2
+*   cifs/index
+*   dell_rbu
+*   device-mapper/index
+*   edid
+*   efi-stub
+*   ext4
+*   nfs/index
+*   gpio/index
+*   highuid
+*   hw_random
+*   initrd
+*   iostats
+*   java
+*   jfs
+*   kernel-per-CPU-kthreads
+*   laptops/index
+*   lcd-panel-cgram
+*   ldm
+*   LSM/index
+*   md
+*   media/index
+*   module-signing
+*   mono
+*   namespaces/index
+*   numastat
+*   parport
+*   perf-security
+*   pm/index
+*   pnp
+*   rapidio
+*   ras
+*   rtc
+*   serial-console
+*   svga
+*   thunderbolt
+*   ufs
+*   vga-softcursor
+*   video-output
+*   xfs
 
 .. only::  subproject and html
 
diff --git a/Documentation/translations/zh_TW/admin-guide/init.rst b/Documentation/translations/zh_TW/admin-guide/init.rst
index 32cdf134948f..be6e34f5f7fa 100644
--- a/Documentation/translations/zh_TW/admin-guide/init.rst
+++ b/Documentation/translations/zh_TW/admin-guide/init.rst
@@ -7,10 +7,10 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
-解釋「No working init found.」啓動掛起消息
-==========================================
+解釋“No working init found.”啓動掛起消息
+=========================================
 
 :作者:
 
@@ -18,41 +18,41 @@
 
  Cristian Souza <cristianmsbr at gmail period com>
 
-本文檔提供了加載初始化二進位(init binary)失敗的一些高層級原因(大致按執行
+本文檔提供了加載初始化二進制(init binary)失敗的一些高層級原因(大致按執行
 順序列出)。
 
-1) **無法掛載根文件系統Unable to mount root FS** :請設置「debug」內核參數(在
+1) **無法掛載根文件系統Unable to mount root FS** :請設置“debug”內核參數(在
    引導加載程序bootloader配置文件或CONFIG_CMDLINE)以獲取更詳細的內核消息。
 
-2) **初始化二進位不存在於根文件系統上init binary doesn't exist on rootfs** :
+2) **初始化二進制不存在於根文件系統上init binary doesn't exist on rootfs** :
    確保您的根文件系統類型正確(並且 ``root=`` 內核參數指向正確的分區);擁有
-   所需的驅動程序,例如SCSI或USB等存儲硬體;文件系統(ext3、jffs2等)是內建的
+   所需的驅動程序,例如SCSI或USB等存儲硬件;文件系統(ext3、jffs2等)是內建的
    (或者作爲模塊由initrd預加載)。
 
-3) **控制台設備損壞Broken console device** : ``console= setup`` 中可能存在
-   衝突 --> 初始控制台不可用(initial console unavailable)。例如,由於串行
-   IRQ問題(如缺少基於中斷的配置)導致的某些串行控制台不可靠。嘗試使用不同的
+3) **控制檯設備損壞Broken console device** : ``console= setup`` 中可能存在
+   衝突 --> 初始控制檯不可用(initial console unavailable)。例如,由於串行
+   IRQ問題(如缺少基於中斷的配置)導致的某些串行控制檯不可靠。嘗試使用不同的
    ``console= device`` 或像 ``netconsole=`` 。
 
-4) **二進位存在但依賴項不可用Binary exists but dependencies not available** :
-   例如初始化二進位的必需庫依賴項,像 ``/lib/ld-linux.so.2`` 丟失或損壞。使用
+4) **二進制存在但依賴項不可用Binary exists but dependencies not available** :
+   例如初始化二進制的必需庫依賴項,像 ``/lib/ld-linux.so.2`` 丟失或損壞。使用
    ``readelf -d <INIT>|grep NEEDED`` 找出需要哪些庫。
 
-5) **無法加載二進位Binary cannot be loaded** :請確保二進位的體系結構與您的
-   硬體匹配。例如i386不匹配x86_64,或者嘗試在ARM硬體上加載x86。如果您嘗試在
-   此處加載非二進位文件(shell腳本?),您應該確保腳本在其工作頭(shebang
+5) **無法加載二進制Binary cannot be loaded** :請確保二進制的體系結構與您的
+   硬件匹配。例如i386不匹配x86_64,或者嘗試在ARM硬件上加載x86。如果您嘗試在
+   此處加載非二進制文件(shell腳本?),您應該確保腳本在其工作頭(shebang
    header)行 ``#!/...`` 中指定能正常工作的解釋器(包括其庫依賴項)。在處理
-   腳本之前,最好先測試一個簡單的非腳本二進位文件,比如 ``/bin/sh`` ,並確認
+   腳本之前,最好先測試一個簡單的非腳本二進制文件,比如 ``/bin/sh`` ,並確認
    它能成功執行。要了解更多信息,請將代碼添加到 ``init/main.c`` 以顯示
    kernel_execve()的返回值。
 
-當您發現新的失敗原因時,請擴展本解釋(畢竟加載初始化二進位是一個 **關鍵** 且
+當您發現新的失敗原因時,請擴展本解釋(畢竟加載初始化二進制是一個 **關鍵** 且
 艱難的過渡步驟,需要儘可能無痛地進行),然後向LKML提交一個補丁。
 
 待辦事項:
 
 - 通過一個可以存儲 ``kernel_execve()`` 結果值的結構體數組實現各種
-  ``run_init_process()`` 調用,並在失敗時通過疊代 **所有** 結果來記錄一切
+  ``run_init_process()`` 調用,並在失敗時通過迭代 **所有** 結果來記錄一切
   (非常重要的可用性修復)。
-- 試著使實現本身在一般情況下更有幫助,例如在受影響的地方提供額外的錯誤消息。
+- 試着使實現本身在一般情況下更有幫助,例如在受影響的地方提供額外的錯誤消息。
 
diff --git a/Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst b/Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst
new file mode 100644
index 000000000000..64a28637c853
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst
@@ -0,0 +1,69 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/lockup-watchdogs.rst
+:Translator: Hailong Liu <liu.hailong6@zte.com.cn>
+
+.. _tw_lockup-watchdogs:
+
+
+=================================================
+Softlockup與hardlockup檢測機制(又名:nmi_watchdog)
+=================================================
+
+Linux中內核實現了一種用以檢測系統發生softlockup和hardlockup的看門狗機制。
+
+Softlockup是一種會引發系統在內核態中一直循環超過20秒(詳見下面“實現”小節)導致
+其他任務沒有機會得到運行的BUG。一旦檢測到'softlockup'發生,默認情況下系統會打
+印當前堆棧跟蹤信息並進入鎖定狀態。也可配置使其在檢測到'softlockup'後進入panic
+狀態;通過sysctl命令設置“kernel.softlockup_panic”、使用內核啓動參數
+“softlockup_panic”(詳見Documentation/admin-guide/kernel-parameters.rst)以及使
+能內核編譯選項“BOOTPARAM_SOFTLOCKUP_PANIC”都可實現這種配置。
+
+而'hardlockup'是一種會引發系統在內核態一直循環超過10秒鐘(詳見"實現"小節)導致其
+他中斷沒有機會運行的缺陷。與'softlockup'情況類似,除了使用sysctl命令設置
+'hardlockup_panic'、使能內核選項“BOOTPARAM_HARDLOCKUP_PANIC”以及使用內核參數
+"nmi_watchdog"(詳見:”Documentation/admin-guide/kernel-parameters.rst“)外,一旦檢
+測到'hardlockup'默認情況下系統打印當前堆棧跟蹤信息,然後進入鎖定狀態。
+
+這個panic選項也可以與panic_timeout結合使用(這個panic_timeout是通過稍具迷惑性的
+sysctl命令"kernel.panic"來設置),使系統在panic指定時間後自動重啓。
+
+實現
+====
+
+Softlockup和hardlockup分別建立在hrtimer(高精度定時器)和perf兩個子系統上而實現。
+這也就意味着理論上任何架構只要實現了這兩個子系統就支持這兩種檢測機制。
+
+Hrtimer用於週期性產生中斷並喚醒watchdog線程;NMI perf事件則以”watchdog_thresh“
+(編譯時默認初始化爲10秒,也可通過”watchdog_thresh“這個sysctl接口來進行配置修改)
+爲間隔週期產生以檢測 hardlockups。如果一個CPU在這個時間段內沒有檢測到hrtimer中
+斷髮生,'hardlockup 檢測器'(即NMI perf事件處理函數)將會視系統配置而選擇產生內核
+警告或者直接panic。
+
+而watchdog線程本質上是一個高優先級內核線程,每調度一次就對時間戳進行一次更新。
+如果時間戳在2*watchdog_thresh(這個是softlockup的觸發門限)這段時間都未更新,那麼
+"softlocup 檢測器"(內部hrtimer定時器回調函數)會將相關的調試信息打印到系統日誌中,
+然後如果系統配置了進入panic流程則進入panic,否則內核繼續執行。
+
+Hrtimer定時器的週期是2*watchdog_thresh/5,也就是說在hardlockup被觸發前hrtimer有
+2~3次機會產生時鐘中斷。
+
+如上所述,內核相當於爲系統管理員提供了一個可調節hrtimer定時器和perf事件週期長度
+的調節旋鈕。如何通過這個旋鈕爲特定使用場景配置一個合理的週期值要對lockups檢測的
+響應速度和lockups檢測開銷這二者之間進行權衡。
+
+默認情況下所有在線cpu上都會運行一個watchdog線程。不過在內核配置了”NO_HZ_FULL“的
+情況下watchdog線程默認只會運行在管家(housekeeping)cpu上,而”nohz_full“啓動參數指
+定的cpu上則不會有watchdog線程運行。試想,如果我們允許watchdog線程在”nohz_full“指
+定的cpu上運行,這些cpu上必須得運行時鐘定時器來激發watchdog線程調度;這樣一來就會
+使”nohz_full“保護用戶程序免受內核干擾的功能失效。當然,副作用就是”nohz_full“指定
+的cpu即使在內核產生了lockup問題我們也無法檢測到。不過,至少我們可以允許watchdog
+線程在管家(non-tickless)核上繼續運行以便我們能繼續正常的監測這些cpus上的lockups
+事件。
+
+不論哪種情況都可以通過sysctl命令kernel.watchdog_cpumask來對沒有運行watchdog線程
+的cpu集合進行調節。對於nohz_full而言,如果nohz_full cpu上有異常掛住的情況,通過
+這種方式打開這些cpu上的watchdog進行調試可能會有所作用。
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst
new file mode 100644
index 000000000000..1900692f1c75
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst
@@ -0,0 +1,31 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/index.rst
+
+:翻譯:
+
+ 司延騰 Yanteng Si <siyanteng@loongson.cn>
+
+:校譯:
+
+============
+監測數據訪問
+============
+
+:doc:`DAMON </mm/damon/index>` 允許輕量級的數據訪問監測。使用DAMON,
+用戶可以分析他們系統的內存訪問模式,並優化它們。
+
+.. toctree::
+   :maxdepth: 2
+
+   start
+   usage
+   reclaim
+   lru_sort
+
+
+
+
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst
new file mode 100644
index 000000000000..01cea8784b6e
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst
@@ -0,0 +1,265 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/lru_sort.rst
+
+:翻譯:
+
+ 臧雷剛 Leigang Zang <zangleigang@hisilicon.com>
+
+:校譯:
+
+==================
+基於DAMON的LRU排序
+==================
+
+基於DAMON的LRU排序是一個靜態的內核模塊,旨在用於以主動的、輕量級的數據訪問模型
+爲基礎的頁面優先級處理的LRU鏈表上,以使得LRU上的數據訪問模型更爲可信。
+
+哪裏需要主動的LRU排序
+=====================
+
+在一個大型系統中,以頁爲粒度的訪問檢測會有比較顯著的開銷,LRU通常不會主動去排序,
+而是對部分特殊事件進行部分的、響應式的排序,例如:特殊的用戶請求,系統調用或者
+內存壓力。這導致,在有些場景下,LRU不能夠完美的作爲一個可信的數據訪問模型,比如
+在內存壓力下對目標內存進行回收。
+
+因爲DAMON能夠儘可能準確的識別數據訪問模型,同時只引起用戶指定範圍的開銷,主動的
+執行DAMON_LRU_SORT讓LRU變得更爲可信是有益的,而且這隻需要較少和可控的開銷。
+
+這是如何工作的
+==============
+
+DAMON_LRU_SORT使用DAMON尋找熱頁(範圍內的頁面訪問頻率高於用戶指定的閾值)和冷頁
+(範圍內的頁面在超過用戶指定的時間無訪問),並提高熱頁和降低冷頁在LRU中的優先級。
+爲了避免在排序過程佔用更多的CPU計算資源,可以設置一個CPU佔用時間的約束值。在約
+束下,分別提升或者降低更多的熱頁和冷頁。系統管理員也可以配置三個內存水位以控制
+在何種條件下自動激活或者停止這種機制。
+
+冷熱閾值和CPU約束的默認值是比較保守的。這意味着,在默認參數下,模塊可以廣泛且無
+負作用的使用在常見環境中,同時在只消耗一小部分CPU時間的情況下,給有內存壓力的系
+統提供一定水平的冷熱識別。
+
+接口:模塊參數
+==============
+
+使用此特性,你首先需要確認你的系統中運行的內核在編譯時啓用了
+``CONFIG_DAMON_LRU_SORT=y``.
+
+爲了讓系統管理員打開或者關閉並且調節指定的系統,DAMON_LRU_SORT設計了模塊參數。
+這意味着,你可以添加 ``damon_lru_sort.<parameter>=<value>`` 到內核的啓動命令行
+參數,或者在 ``/sys/modules/damon_lru_sort/parameters/<parameter>`` 寫入正確的
+值。
+
+下邊是每個參數的描述
+
+enabled
+-------
+
+打開或者關閉DAMON_LRU_SORT.
+
+你可以通過設置這個參數爲 ``Y`` 來打開DAMON_LRU_SORT。設置爲 ``N`` 關閉
+DAMON_LRU_SORT。注意,在基於水位的激活的情況下,DAMON_LRU_SORT有可能不會真正去
+監測或者做LRU排序。對這種情況,參考下方關於水位的描述。
+
+commit_inputs
+-------------
+
+讓DAMON_LRU_SORT再次讀取輸入參數,除了 ``enabled`` 。
+
+在DAMON_LRU_SORT運行時,新的輸入參數默認不會被應用。一旦這個參數被設置爲 ``Y``
+,DAMON_LRU_SORT會再次讀取除了 ``enabled`` 之外的參數。讀取完成後,這個參數會被
+設置爲 ``N`` 。如果在讀取時發現有無效參數,DAMON_LRU_SORT會被關閉。
+
+hot_thres_access_freq
+---------------------
+
+熱點內存區域的訪問頻率閾值,千分比。
+
+如果一個內存區域的訪問頻率大於等於這個值,DAMON_LRU_SORT把這個區域看作熱區,並
+在LRU上把這個區域標記爲已訪問,因些在內存壓力下這部分內存不會被回收。默認爲50%。
+
+cold_min_age
+------------
+
+用於識別冷內存區域的時間閾值,單位是微秒。
+
+如果一個內存區域在這個時間內未被訪問過,DAMON_LRU_SORT把這個區域看作冷區,並在
+LRU上把這個區域標記爲未訪問,因此在內存壓力下這些內存會首先被回收。默認值爲120
+秒。
+
+quota_ms
+--------
+
+嘗試LRU鏈表排序的時間限制,單位是毫秒。
+
+DAMON_LRU_SORT在一個時間窗口內(quota_reset_interval_ms)內最多嘗試這麼長時間來
+對LRU進行排序。這個可以用來作爲CPU計算資源的約束。如果值爲0,則表示無限制。
+
+默認10毫秒。
+
+quota_reset_interval_ms
+-----------------------
+
+配額計時重置週期,毫秒。
+
+配額計時重置週期。即,在quota_reset_interval_ms毫秒內,DAMON_LRU_SORT對LRU進行
+排序不會超過quota_ms或者quota_sz。
+
+默認1秒。
+
+wmarks_interval
+---------------
+
+水位的檢查週期,單位是微秒。
+
+當DAMON_LRU_SORT使能但是由於水位而不活躍時檢查水位前最小的等待時間。默認值5秒。
+
+wmarks_high
+-----------
+
+空閒內存高水位,千分比。
+
+如果空閒內存水位高於這個值,DAMON_LRU_SORT停止工作,不做任何事,除了週期性的檢
+查水位。默認200(20%)。
+
+wmarks_mid
+----------
+
+空閒內存中間水位,千分比。
+
+如果空閒內存水位在這個值與低水位之間,DAMON_LRU_SORT開始工作,開始檢測並對LRU鏈
+表進行排序。默認150(15%)。
+
+wmarks_low
+----------
+
+空閒內存低水位,千分比。
+
+如果空閒內存小於這個值,DAMON_LRU_SORT不再工作,不做任何事,除了週期性的檢查水
+線。默認50(5%)。
+
+sample_interval
+---------------
+
+監測的採樣週期,微秒。
+
+DAMON對冷內存監測的採樣週期。更多細節請參考DAMON文檔 (:doc:`usage`) 。默認5
+毫秒。
+
+aggr_interval
+-------------
+
+監測的收集週期,微秒。
+
+DAMON對冷內存進行收集的時間週期。更多細節請參考DAMON文檔 (:doc:`usage`) 。默認
+100毫秒。
+
+min_nr_regions
+--------------
+
+最小監測區域數量。
+
+對冷內存區域監測的最小數量。這個值可以作爲監測質量的下限。不過,這個值設置的過
+大會增加開銷。更多細節請參考DAMON文檔 (:doc:`usage`) 。默認值爲10。
+
+max_nr_regions
+--------------
+
+最大監測區域數量。
+
+對冷內存區域監測的最大數量。這個值可以作爲監測質量的上限。然而,這個值設置的過
+低會導致監測結果變差。更多細節請參考DAMON文檔 (:doc:`usage`) 。默認值爲1000。
+
+monitor_region_start
+--------------------
+
+目標內存區域的起始物理地址。
+
+DAMON_LRU_SORT要處理的目標內存區域的起始物理地址。默認,使用系統最大內存。
+
+monitor_region_end
+------------------
+
+目標內存區域的結束物理地址。
+
+DAMON_LRU_SORT要處理的目標內存區域的結束物理地址。默認,使用系統最大內存。
+
+kdamond_pid
+-----------
+
+DAMON線程的PID。
+
+如果DAMON_LRU_SORT是使能的,這個表示任務線程的PID。其它情況爲-1。
+
+nr_lru_sort_tried_hot_regions
+-----------------------------
+
+被嘗試進行LRU排序的熱內存區域的數量。
+
+bytes_lru_sort_tried_hot_regions
+--------------------------------
+
+被嘗試進行LRU排序的熱內存區域的大小(字節)。
+
+nr_lru_sorted_hot_regions
+-------------------------
+
+成功進行LRU排序的熱內存區域的數量。
+
+bytes_lru_sorted_hot_regions
+----------------------------
+
+成功進行LRU排序的熱內存區域的大小(字節)。
+
+nr_hot_quota_exceeds
+--------------------
+
+熱區域時間約束超過限制的次數。
+
+nr_lru_sort_tried_cold_regions
+------------------------------
+
+被嘗試進行LRU排序的冷內存區域的數量。
+
+bytes_lru_sort_tried_cold_regions
+---------------------------------
+
+被嘗試進行LRU排序的冷內存區域的大小(字節)。
+
+nr_lru_sorted_cold_regions
+--------------------------
+
+成功進行LRU排序的冷內存區域的數量。
+
+bytes_lru_sorted_cold_regions
+-----------------------------
+
+成功進行LRU排序的冷內存區域的大小(字節)。
+
+nr_cold_quota_exceeds
+---------------------
+
+冷區域時間約束超過限制的次數。
+
+Example
+=======
+
+如下是一個運行時的命令示例,使DAMON_LRU_SORT查找訪問頻率超過50%的區域並對其進行
+LRU的優先級的提升,同時降低那些超過120秒無人訪問的內存區域的優先級。優先級的處
+理被限制在最多1%的CPU以避免DAMON_LRU_SORT消費過多CPU時間。在系統空閒內存超過50%
+時DAMON_LRU_SORT停止工作,並在低於40%時重新開始工作。如果DAMON_RECLAIM沒有取得
+進展且空閒內存低於20%,再次讓DAMON_LRU_SORT停止工作,以此回退到以LRU鏈表爲基礎
+以頁面爲單位的內存回收上。 ::
+
+    # cd /sys/modules/damon_lru_sort/parameters
+    # echo 500 > hot_thres_access_freq
+    # echo 120000000 > cold_min_age
+    # echo 10 > quota_ms
+    # echo 1000 > quota_reset_interval_ms
+    # echo 500 > wmarks_high
+    # echo 400 > wmarks_mid
+    # echo 200 > wmarks_low
+    # echo Y > enabled
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst
new file mode 100644
index 000000000000..a390712d5792
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst
@@ -0,0 +1,230 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/reclaim.rst
+
+:翻譯:
+
+ 司延騰 Yanteng Si <siyanteng@loongson.cn>
+
+:校譯:
+
+===============
+基於DAMON的回收
+===============
+
+基於DAMON的回收(DAMON_RECLAIM)是一個靜態的內核模塊,旨在用於輕度內存壓力下的主動和輕
+量級的回收。它的目的不是取代基於LRU列表的頁面回收,而是有選擇地用於不同程度的內存壓力和要
+求。
+
+哪些地方需要主動回收?
+======================
+
+在一般的內存超量使用(over-committed systems,虛擬化相關術語)的系統上,主動回收冷頁
+有助於節省內存和減少延遲高峯,這些延遲是由直接回收進程或kswapd的CPU消耗引起的,同時只產
+生最小的性能下降 [1]_ [2]_ 。
+
+基於空閒頁報告 [3]_ 的內存過度承諾的虛擬化系統就是很好的例子。在這樣的系統中,客戶機
+向主機報告他們的空閒內存,而主機則將報告的內存重新分配給其他客戶。因此,系統的內存得到了充
+分的利用。然而,客戶可能不那麼節省內存,主要是因爲一些內核子系統和用戶空間應用程序被設計爲
+使用盡可能多的內存。然後,客戶機可能只向主機報告少量的內存是空閒的,導致系統的內存利用率下降。
+在客戶中運行主動回收可以緩解這個問題。
+
+它是如何工作的?
+================
+
+DAMON_RECLAIM找到在特定時間內沒有被訪問的內存區域並分頁。爲了避免它在分頁操作中消耗過多
+的CPU,可以配置一個速度限制。在這個速度限制下,它首先分頁出那些沒有被訪問過的內存區域。系
+統管理員還可以配置在什麼情況下這個方案應該自動激活和停用三個內存壓力水位。
+
+接口: 模塊參數
+==============
+
+要使用這個功能,你首先要確保你的系統運行在一個以 ``CONFIG_DAMON_RECLAIM=y`` 構建的內
+核上。
+
+爲了讓系統管理員啓用或禁用它,併爲給定的系統進行調整,DAMON_RECLAIM利用了模塊參數。也就
+是說,你可以把 ``damon_reclaim.<parameter>=<value>`` 放在內核啓動命令行上,或者把
+適當的值寫入 ``/sys/module/damon_reclaim/parameters/<parameter>`` 文件。
+
+下面是每個參數的描述。
+
+enabled
+-------
+
+啓用或禁用DAMON_RECLAIM。
+
+你可以通過把這個參數的值設置爲 ``Y`` 來啓用DAMON_RCLAIM,把它設置爲 ``N`` 可以禁用
+DAMON_RECLAIM。注意,由於基於水位的激活條件,DAMON_RECLAIM不能進行真正的監測和回收。
+這一點請參考下面關於水位參數的描述。
+
+min_age
+-------
+
+識別冷內存區域的時間閾值,單位是微秒。
+
+如果一個內存區域在這個時間或更長的時間內沒有被訪問,DAMON_RECLAIM會將該區域識別爲冷的,
+並回收它。
+
+默認爲120秒。
+
+quota_ms
+--------
+
+回收的時間限制,以毫秒爲單位。
+
+DAMON_RECLAIM 試圖在一個時間窗口(quota_reset_interval_ms)內只使用到這個時間,以
+嘗試回收冷頁。這可以用來限制DAMON_RECLAIM的CPU消耗。如果該值爲零,則該限制被禁用。
+
+默認爲10ms。
+
+quota_sz
+--------
+
+回收的內存大小限制,單位爲字節。
+
+DAMON_RECLAIM 收取在一個時間窗口(quota_reset_interval_ms)內試圖回收的內存量,並
+使其不超過這個限制。這可以用來限制CPU和IO的消耗。如果該值爲零,則限制被禁用。
+
+默認情況下是128 MiB。
+
+quota_reset_interval_ms
+-----------------------
+
+時間/大小配額收取重置間隔,單位爲毫秒。
+
+時間(quota_ms)和大小(quota_sz)的配額的目標重置間隔。也就是說,DAMON_RECLAIM在
+嘗試回收‘不’超過quota_ms毫秒或quota_sz字節的內存。
+
+默認爲1秒。
+
+wmarks_interval
+---------------
+
+當DAMON_RECLAIM被啓用但由於其水位規則而不活躍時,在檢查水位之前的最小等待時間。
+
+wmarks_high
+-----------
+
+高水位的可用內存率(每千字節)。
+
+如果系統的可用內存(以每千字節爲單位)高於這個數值,DAMON_RECLAIM就會變得不活躍,所以
+它什麼也不做,只是定期檢查水位。
+
+wmarks_mid
+----------
+
+中間水位的可用內存率(每千字節)。
+
+如果系統的空閒內存(以每千字節爲單位)在這個和低水位線之間,DAMON_RECLAIM就會被激活,
+因此開始監測和回收。
+
+wmarks_low
+----------
+
+低水位的可用內存率(每千字節)。
+
+如果系統的空閒內存(以每千字節爲單位)低於這個數值,DAMON_RECLAIM就會變得不活躍,所以
+它除了定期檢查水位外什麼都不做。在這種情況下,系統會退回到基於LRU列表的頁面粒度回收邏輯。
+
+sample_interval
+---------------
+
+監測的採樣間隔,單位是微秒。
+
+DAMON用於監測冷內存的採樣間隔。更多細節請參考DAMON文檔 (:doc:`usage`) 。
+
+aggr_interval
+-------------
+
+監測的聚集間隔,單位是微秒。
+
+DAMON對冷內存監測的聚集間隔。更多細節請參考DAMON文檔 (:doc:`usage`)。
+
+min_nr_regions
+--------------
+
+監測區域的最小數量。
+
+DAMON用於冷內存監測的最小監測區域數。這可以用來設置監測質量的下限。但是,設
+置的太高可能會導致監測開銷的增加。更多細節請參考DAMON文檔 (:doc:`usage`) 。
+
+max_nr_regions
+--------------
+
+監測區域的最大數量。
+
+DAMON用於冷內存監測的最大監測區域數。這可以用來設置監測開銷的上限值。但是,
+設置得太低可能會導致監測質量不好。更多細節請參考DAMON文檔 (:doc:`usage`) 。
+
+monitor_region_start
+--------------------
+
+目標內存區域的物理地址起點。
+
+DAMON_RECLAIM將對其進行工作的內存區域的起始物理地址。也就是說,DAMON_RECLAIM
+將在這個區域中找到冷的內存區域並進行回收。默認情況下,該區域使用最大系統內存區。
+
+monitor_region_end
+------------------
+
+目標內存區域的結束物理地址。
+
+DAMON_RECLAIM將對其進行工作的內存區域的末端物理地址。也就是說,DAMON_RECLAIM將
+在這個區域內找到冷的內存區域並進行回收。默認情況下,該區域使用最大系統內存區。
+
+kdamond_pid
+-----------
+
+DAMON線程的PID。
+
+如果DAMON_RECLAIM被啓用,這將成爲工作線程的PID。否則,爲-1。
+
+nr_reclaim_tried_regions
+------------------------
+
+試圖通過DAMON_RECLAIM回收的內存區域的數量。
+
+bytes_reclaim_tried_regions
+---------------------------
+
+試圖通過DAMON_RECLAIM回收的內存區域的總字節數。
+
+nr_reclaimed_regions
+--------------------
+
+通過DAMON_RECLAIM成功回收的內存區域的數量。
+
+bytes_reclaimed_regions
+-----------------------
+
+通過DAMON_RECLAIM成功回收的內存區域的總字節數。
+
+nr_quota_exceeds
+----------------
+
+超過時間/空間配額限制的次數。
+
+例子
+====
+
+下面的運行示例命令使DAMON_RECLAIM找到30秒或更長時間沒有訪問的內存區域並“回收”?
+爲了避免DAMON_RECLAIM在分頁操作中消耗過多的CPU時間,回收被限制在每秒1GiB以內。
+它還要求DAMON_RECLAIM在系統的可用內存率超過50%時不做任何事情,但如果它低於40%時
+就開始真正的工作。如果DAMON_RECLAIM沒有取得進展,因此空閒內存率低於20%,它會要求
+DAMON_RECLAIM再次什麼都不做,這樣我們就可以退回到基於LRU列表的頁面粒度回收了::
+
+    # cd /sys/module/damon_reclaim/parameters
+    # echo 30000000 > min_age
+    # echo $((1 * 1024 * 1024 * 1024)) > quota_sz
+    # echo 1000 > quota_reset_interval_ms
+    # echo 500 > wmarks_high
+    # echo 400 > wmarks_mid
+    # echo 200 > wmarks_low
+    # echo Y > enabled
+
+.. [1] https://research.google/pubs/pub48551/
+.. [2] https://lwn.net/Articles/787611/
+.. [3] https://www.kernel.org/doc/html/latest/mm/free_page_reporting.html
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst
new file mode 100644
index 000000000000..9b8be5addd45
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst
@@ -0,0 +1,126 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/start.rst
+
+:翻譯:
+
+ 司延騰 Yanteng Si <siyanteng@loongson.cn>
+
+:校譯:
+
+========
+入門指南
+========
+
+本文通過演示DAMON的默認用戶空間工具,簡要地介紹瞭如何使用DAMON。請注意,爲了簡潔
+起見,本文檔只描述了它的部分功能。更多細節請參考該工具的使用文檔。
+`doc <https://github.com/awslabs/damo/blob/next/USAGE.md>`_ .
+
+
+前提條件
+========
+
+內核
+----
+
+首先,你要確保你當前系統中跑的內核構建時選定了這個功能選項 ``CONFIG_DAMON_*=y``.
+
+
+用戶空間工具
+------------
+
+在演示中,我們將使用DAMON的默認用戶空間工具,稱爲DAMON Operator(DAMO)。它可以在
+https://github.com/awslabs/damo找到。下面的例子假設DAMO在你的$PATH上。當然,但
+這並不是強制性的。
+
+因爲DAMO使用了DAMON的sysfs接口(詳情請參考:doc:`usage`),你應該確保
+:doc:`sysfs </filesystems/sysfs>` 被掛載。
+
+記錄數據訪問模式
+================
+
+下面的命令記錄了一個程序的內存訪問模式,並將監測結果保存到文件中。 ::
+
+    $ git clone https://github.com/sjp38/masim
+    $ cd masim; make; ./masim ./configs/zigzag.cfg &
+    $ sudo damo record -o damon.data $(pidof masim)
+
+命令的前兩行下載了一個人工內存訪問生成器程序並在後臺運行。生成器將重複地逐一訪問兩個
+100 MiB大小的內存區域。你可以用你的真實工作負載來代替它。最後一行要求 ``damo`` 將
+訪問模式記錄在 ``damon.data`` 文件中。
+
+
+將記錄的模式可視化
+==================
+
+你可以在heatmap中直觀地看到這種模式,顯示哪個內存區域(X軸)何時被訪問(Y軸)以及訪
+問的頻率(數字)。::
+
+    $ sudo damo report heats --heatmap stdout
+    22222222222222222222222222222222222222211111111111111111111111111111111111111100
+    44444444444444444444444444444444444444434444444444444444444444444444444444443200
+    44444444444444444444444444444444444444433444444444444444444444444444444444444200
+    33333333333333333333333333333333333333344555555555555555555555555555555555555200
+    33333333333333333333333333333333333344444444444444444444444444444444444444444200
+    22222222222222222222222222222222222223355555555555555555555555555555555555555200
+    00000000000000000000000000000000000000288888888888888888888888888888888888888400
+    00000000000000000000000000000000000000288888888888888888888888888888888888888400
+    33333333333333333333333333333333333333355555555555555555555555555555555555555200
+    88888888888888888888888888888888888888600000000000000000000000000000000000000000
+    88888888888888888888888888888888888888600000000000000000000000000000000000000000
+    33333333333333333333333333333333333333444444444444444444444444444444444444443200
+    00000000000000000000000000000000000000288888888888888888888888888888888888888400
+    [...]
+    # access_frequency:  0  1  2  3  4  5  6  7  8  9
+    # x-axis: space (139728247021568-139728453431248: 196.848 MiB)
+    # y-axis: time (15256597248362-15326899978162: 1 m 10.303 s)
+    # resolution: 80x40 (2.461 MiB and 1.758 s for each character)
+
+你也可以直觀地看到工作集的大小分佈,按大小排序。::
+
+    $ sudo damo report wss --range 0 101 10
+    # <percentile> <wss>
+    # target_id     18446632103789443072
+    # avr:  107.708 MiB
+      0             0 B |                                                           |
+     10      95.328 MiB |****************************                               |
+     20      95.332 MiB |****************************                               |
+     30      95.340 MiB |****************************                               |
+     40      95.387 MiB |****************************                               |
+     50      95.387 MiB |****************************                               |
+     60      95.398 MiB |****************************                               |
+     70      95.398 MiB |****************************                               |
+     80      95.504 MiB |****************************                               |
+     90     190.703 MiB |*********************************************************  |
+    100     196.875 MiB |***********************************************************|
+
+在上述命令中使用 ``--sortby`` 選項,可以顯示工作集的大小是如何按時間順序變化的。::
+
+    $ sudo damo report wss --range 0 101 10 --sortby time
+    # <percentile> <wss>
+    # target_id     18446632103789443072
+    # avr:  107.708 MiB
+      0       3.051 MiB |                                                           |
+     10     190.703 MiB |***********************************************************|
+     20      95.336 MiB |*****************************                              |
+     30      95.328 MiB |*****************************                              |
+     40      95.387 MiB |*****************************                              |
+     50      95.332 MiB |*****************************                              |
+     60      95.320 MiB |*****************************                              |
+     70      95.398 MiB |*****************************                              |
+     80      95.398 MiB |*****************************                              |
+     90      95.340 MiB |*****************************                              |
+    100      95.398 MiB |*****************************                              |
+
+
+數據訪問模式感知的內存管理
+==========================
+
+以下三個命令使每一個大小>=4K的內存區域在你的工作負載中沒有被訪問>=60秒,就會被換掉。 ::
+
+    $ echo "#min-size max-size min-acc max-acc min-age max-age action" > test_scheme
+    $ echo "4K        max      0       0       60s     max     pageout" >> test_scheme
+    $ damo schemes -c test_scheme <pid of your workload>
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst
new file mode 100644
index 000000000000..ac1af36bb17d
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst
@@ -0,0 +1,593 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/usage.rst
+
+:翻譯:
+
+ 司延騰 Yanteng Si <siyanteng@loongson.cn>
+
+:校譯:
+
+========
+詳細用法
+========
+
+DAMON 爲不同的用戶提供了下面這些接口。
+
+- *DAMON用戶空間工具。*
+  `這 <https://github.com/awslabs/damo>`_ 爲有這特權的人, 如系統管理員,希望有一個剛好
+  可以工作的人性化界面。
+  使用它,用戶可以以人性化的方式使用DAMON的主要功能。不過,它可能不會爲特殊情況進行高度調整。
+  它同時支持虛擬和物理地址空間的監測。更多細節,請參考它的 `使用文檔
+  <https://github.com/awslabs/damo/blob/next/USAGE.md>`_。
+- *sysfs接口。*
+  :ref:`這 <sysfs_interface>` 是爲那些希望更高級的使用DAMON的特權用戶空間程序員準備的。
+  使用它,用戶可以通過讀取和寫入特殊的sysfs文件來使用DAMON的主要功能。因此,你可以編寫和使
+  用你個性化的DAMON sysfs包裝程序,代替你讀/寫sysfs文件。  `DAMON用戶空間工具
+  <https://github.com/awslabs/damo>`_ 就是這種程序的一個例子  它同時支持虛擬和物理地址
+  空間的監測。注意,這個界面只提供簡單的監測結果 :ref:`統計 <damos_stats>`。對於詳細的監測
+  結果,DAMON提供了一個:ref:`跟蹤點 <tracepoint>`。
+- *debugfs interface.*
+  :ref:`這 <debugfs_interface>` 幾乎與:ref:`sysfs interface <sysfs_interface>` 接
+  口相同。這將在下一個LTS內核發佈後被移除,所以用戶應該轉移到
+  :ref:`sysfs interface <sysfs_interface>`。
+- *內核空間編程接口。*
+  :doc:`這 </mm/damon/api>` 這是爲內核空間程序員準備的。使用它,用戶可以通過爲你編寫內
+  核空間的DAMON應用程序,最靈活有效地利用DAMON的每一個功能。你甚至可以爲各種地址空間擴展DAMON。
+  詳細情況請參考接口 :doc:`文件 </mm/damon/api>`。
+
+sysfs接口
+=========
+DAMON的sysfs接口是在定義 ``CONFIG_DAMON_SYSFS`` 時建立的。它在其sysfs目錄下創建多
+個目錄和文件, ``<sysfs>/kernel/mm/damon/`` 。你可以通過對該目錄下的文件進行寫入和
+讀取來控制DAMON。
+
+對於一個簡短的例子,用戶可以監測一個給定工作負載的虛擬地址空間,如下所示::
+
+    # cd /sys/kernel/mm/damon/admin/
+    # echo 1 > kdamonds/nr_kdamonds && echo 1 > kdamonds/0/contexts/nr_contexts
+    # echo vaddr > kdamonds/0/contexts/0/operations
+    # echo 1 > kdamonds/0/contexts/0/targets/nr_targets
+    # echo $(pidof <workload>) > kdamonds/0/contexts/0/targets/0/pid_target
+    # echo on > kdamonds/0/state
+
+文件層次結構
+------------
+
+DAMON sysfs接口的文件層次結構如下圖所示。在下圖中,父子關係用縮進表示,每個目錄有
+``/`` 後綴,每個目錄中的文件用逗號(",")分開。 ::
+
+    /sys/kernel/mm/damon/admin
+    │ kdamonds/nr_kdamonds
+    │ │ 0/state,pid
+    │ │ │ contexts/nr_contexts
+    │ │ │ │ 0/operations
+    │ │ │ │ │ monitoring_attrs/
+    │ │ │ │ │ │ intervals/sample_us,aggr_us,update_us
+    │ │ │ │ │ │ nr_regions/min,max
+    │ │ │ │ │ targets/nr_targets
+    │ │ │ │ │ │ 0/pid_target
+    │ │ │ │ │ │ │ regions/nr_regions
+    │ │ │ │ │ │ │ │ 0/start,end
+    │ │ │ │ │ │ │ │ ...
+    │ │ │ │ │ │ ...
+    │ │ │ │ │ schemes/nr_schemes
+    │ │ │ │ │ │ 0/action
+    │ │ │ │ │ │ │ access_pattern/
+    │ │ │ │ │ │ │ │ sz/min,max
+    │ │ │ │ │ │ │ │ nr_accesses/min,max
+    │ │ │ │ │ │ │ │ age/min,max
+    │ │ │ │ │ │ │ quotas/ms,bytes,reset_interval_ms
+    │ │ │ │ │ │ │ │ weights/sz_permil,nr_accesses_permil,age_permil
+    │ │ │ │ │ │ │ watermarks/metric,interval_us,high,mid,low
+    │ │ │ │ │ │ │ stats/nr_tried,sz_tried,nr_applied,sz_applied,qt_exceeds
+    │ │ │ │ │ │ │ tried_regions/
+    │ │ │ │ │ │ │ │ 0/start,end,nr_accesses,age
+    │ │ │ │ │ │ │ │ ...
+    │ │ │ │ │ │ ...
+    │ │ │ │ ...
+    │ │ ...
+
+根
+--
+
+DAMON sysfs接口的根是 ``<sysfs>/kernel/mm/damon/`` ,它有一個名爲 ``admin`` 的
+目錄。該目錄包含特權用戶空間程序控制DAMON的文件。擁有根權限的用戶空間工具或deamons可以
+使用這個目錄。
+
+kdamonds/
+---------
+
+與監測相關的信息包括請求規格和結果被稱爲DAMON上下文。DAMON用一個叫做kdamond的內核線程
+執行每個上下文,多個kdamonds可以並行運行。
+
+在 ``admin`` 目錄下,有一個目錄,即``kdamonds``,它有控制kdamonds的文件存在。在開始
+時,這個目錄只有一個文件,``nr_kdamonds``。向該文件寫入一個數字(``N``),就會創建名爲
+``0`` 到 ``N-1`` 的子目錄數量。每個目錄代表每個kdamond。
+
+kdamonds/<N>/
+-------------
+
+在每個kdamond目錄中,存在兩個文件(``state`` 和 ``pid`` )和一個目錄( ``contexts`` )。
+
+讀取 ``state`` 時,如果kdamond當前正在運行,則返回 ``on`` ,如果沒有運行則返回 ``off`` 。
+寫入 ``on`` 或 ``off`` 使kdamond處於狀態。向 ``state`` 文件寫 ``update_schemes_stats`` ,
+更新kdamond的每個基於DAMON的操作方案的統計文件的內容。關於統計信息的細節,請參考
+:ref:`stats section <sysfs_schemes_stats>`. 將 ``update_schemes_tried_regions`` 寫到
+``state`` 文件,爲kdamond的每個基於DAMON的操作方案,更新基於DAMON的操作方案動作的嘗試區域目錄。
+將`clear_schemes_tried_regions`寫入`state`文件,清除kdamond的每個基於DAMON的操作方案的動作
+嘗試區域目錄。 關於基於DAMON的操作方案動作嘗試區域目錄的細節,請參考:ref:tried_regions 部分
+<sysfs_schemes_tried_regions>`。
+
+如果狀態爲 ``on``,讀取 ``pid`` 顯示kdamond線程的pid。
+
+``contexts`` 目錄包含控制這個kdamond要執行的監測上下文的文件。
+
+kdamonds/<N>/contexts/
+----------------------
+
+在開始時,這個目錄只有一個文件,即 ``nr_contexts`` 。向該文件寫入一個數字( ``N`` ),就會創
+建名爲``0`` 到 ``N-1`` 的子目錄數量。每個目錄代表每個監測背景。目前,每個kdamond只支持
+一個上下文,所以只有 ``0`` 或 ``1`` 可以被寫入文件。
+
+contexts/<N>/
+-------------
+
+在每個上下文目錄中,存在一個文件(``operations``)和三個目錄(``monitoring_attrs``,
+``targets``, 和 ``schemes``)。
+
+DAMON支持多種類型的監測操作,包括對虛擬地址空間和物理地址空間的監測。你可以通過向文件
+中寫入以下關鍵詞之一,並從文件中讀取,來設置和獲取DAMON將爲上下文使用何種類型的監測操作。
+
+ - vaddr: 監測特定進程的虛擬地址空間
+ - paddr: 監視系統的物理地址空間
+
+contexts/<N>/monitoring_attrs/
+------------------------------
+
+用於指定監測屬性的文件,包括所需的監測質量和效率,都在 ``monitoring_attrs`` 目錄中。
+具體來說,這個目錄下有兩個目錄,即 ``intervals`` 和 ``nr_regions`` 。
+
+在 ``intervals`` 目錄下,存在DAMON的採樣間隔(``sample_us``)、聚集間隔(``aggr_us``)
+和更新間隔(``update_us``)三個文件。你可以通過寫入和讀出這些文件來設置和獲取微秒級的值。
+
+在 ``nr_regions`` 目錄下,有兩個文件分別用於DAMON監測區域的下限和上限(``min`` 和 ``max`` ),
+這兩個文件控制着監測的開銷。你可以通過向這些文件的寫入和讀出來設置和獲取這些值。
+
+關於間隔和監測區域範圍的更多細節,請參考設計文件 (:doc:`/mm/damon/design`)。
+
+contexts/<N>/targets/
+---------------------
+
+在開始時,這個目錄只有一個文件 ``nr_targets`` 。向該文件寫入一個數字(``N``),就可以創建
+名爲 ``0`` 到 ``N-1`` 的子目錄的數量。每個目錄代表每個監測目標。
+
+targets/<N>/
+------------
+
+在每個目標目錄中,存在一個文件(``pid_target``)和一個目錄(``regions``)。
+
+如果你把 ``vaddr`` 寫到 ``contexts/<N>/operations`` 中,每個目標應該是一個進程。你
+可以通過將進程的pid寫到 ``pid_target`` 文件中來指定DAMON的進程。
+
+targets/<N>/regions
+-------------------
+
+當使用 ``vaddr`` 監測操作集時( ``vaddr`` 被寫入 ``contexts/<N>/operations`` 文
+件),DAMON自動設置和更新監測目標區域,這樣就可以覆蓋目標進程的整個內存映射。然而,用戶可
+能希望將初始監測區域設置爲特定的地址範圍。
+
+相反,當使用 ``paddr`` 監測操作集時,DAMON不會自動設置和更新監測目標區域( ``paddr``
+被寫入 ``contexts/<N>/operations`` 中)。因此,在這種情況下,用戶應該自己設置監測目標
+區域。
+
+在這種情況下,用戶可以按照自己的意願明確設置初始監測目標區域,將適當的值寫入該目錄下的文件。
+
+開始時,這個目錄只有一個文件, ``nr_regions`` 。向該文件寫入一個數字(``N``),就可以創
+建名爲 ``0`` 到  ``N-1`` 的子目錄。每個目錄代表每個初始監測目標區域。
+
+regions/<N>/
+------------
+
+在每個區域目錄中,你會發現兩個文件( ``start``  和  ``end`` )。你可以通過向文件寫入
+和從文件中讀出,分別設置和獲得初始監測目標區域的起始和結束地址。
+
+每個區域不應該與其他區域重疊。 目錄“N”的“結束”應等於或小於目錄“N+1”的“開始”。
+
+contexts/<N>/schemes/
+---------------------
+
+對於一版的基於DAMON的數據訪問感知的內存管理優化,用戶通常希望系統對特定訪問模式的內存區
+域應用內存管理操作。DAMON從用戶那裏接收這種形式化的操作方案,並將這些方案應用於目標內存
+區域。用戶可以通過讀取和寫入這個目錄下的文件來獲得和設置這些方案。
+
+在開始時,這個目錄只有一個文件,``nr_schemes``。向該文件寫入一個數字(``N``),就可以
+創建名爲``0``到``N-1``的子目錄的數量。每個目錄代表每個基於DAMON的操作方案。
+
+schemes/<N>/
+------------
+
+在每個方案目錄中,存在五個目錄(``access_pattern``、``quotas``、``watermarks``、
+``stats`` 和 ``tried_regions``)和一個文件(``action``)。
+
+``action`` 文件用於設置和獲取你想應用於具有特定訪問模式的內存區域的動作。可以寫入文件
+和從文件中讀取的關鍵詞及其含義如下。
+
+ - ``willneed``: 對有 ``MADV_WILLNEED`` 的區域調用 ``madvise()`` 。
+ - ``cold``: 對具有 ``MADV_COLD`` 的區域調用 ``madvise()`` 。
+ - ``pageout``: 爲具有 ``MADV_PAGEOUT`` 的區域調用 ``madvise()`` 。
+ - ``hugepage``: 爲帶有 ``MADV_HUGEPAGE`` 的區域調用 ``madvise()`` 。
+ - ``nohugepage``: 爲帶有 ``MADV_NOHUGEPAGE`` 的區域調用 ``madvise()``。
+ - ``lru_prio``: 在其LRU列表上對區域進行優先排序。
+ - ``lru_deprio``: 對區域的LRU列表進行降低優先處理。
+ - ``stat``: 什麼都不做,只計算統計數據
+
+schemes/<N>/access_pattern/
+---------------------------
+
+每個基於DAMON的操作方案的目標訪問模式由三個範圍構成,包括以字節爲單位的區域大小、每個
+聚合區間的監測訪問次數和區域年齡的聚合區間數。
+
+在 ``access_pattern`` 目錄下,存在三個目錄( ``sz``, ``nr_accesses``, 和 ``age`` ),
+每個目錄有兩個文件(``min`` 和 ``max`` )。你可以通過向  ``sz``, ``nr_accesses``, 和
+``age``  目錄下的 ``min`` 和 ``max`` 文件分別寫入和讀取來設置和獲取給定方案的訪問模式。
+
+schemes/<N>/quotas/
+-------------------
+
+每個 ``動作`` 的最佳 ``目標訪問模式`` 取決於工作負載,所以不容易找到。更糟糕的是,將某些動作
+的方案設置得過於激進會造成嚴重的開銷。爲了避免這種開銷,用戶可以爲每個方案限制時間和大小配額。
+具體來說,用戶可以要求DAMON儘量只使用特定的時間(``時間配額``)來應用動作,並且在給定的時間間
+隔(``重置間隔``)內,只對具有目標訪問模式的內存區域應用動作,而不使用特定數量(``大小配額``)。
+
+當預計超過配額限制時,DAMON會根據 ``目標訪問模式`` 的大小、訪問頻率和年齡,對找到的內存區域
+進行優先排序。爲了進行個性化的優先排序,用戶可以爲這三個屬性設置權重。
+
+在 ``quotas`` 目錄下,存在三個文件(``ms``, ``bytes``, ``reset_interval_ms``)和一個
+目錄(``weights``),其中有三個文件(``sz_permil``, ``nr_accesses_permil``, 和
+``age_permil``)。
+
+你可以設置以毫秒爲單位的 ``時間配額`` ,以字節爲單位的 ``大小配額`` ,以及以毫秒爲單位的 ``重
+置間隔`` ,分別向這三個文件寫入數值。你還可以通過向 ``weights`` 目錄下的三個文件寫入數值來設
+置大小、訪問頻率和年齡的優先權,單位爲千分之一。
+
+schemes/<N>/watermarks/
+-----------------------
+
+爲了便於根據系統狀態激活和停用每個方案,DAMON提供了一個稱爲水位的功能。該功能接收五個值,稱爲
+``度量`` 、``間隔`` 、``高`` 、``中`` 、``低`` 。``度量值`` 是指可以測量的系統度量值,如
+自由內存比率。如果系統的度量值 ``高`` 於memoent的高值或 ``低`` 於低值,則該方案被停用。如果
+該值低於 ``中`` ,則該方案被激活。
+
+在水位目錄下,存在五個文件(``metric``, ``interval_us``,``high``, ``mid``, and ``low``)
+用於設置每個值。你可以通過向這些文件的寫入來分別設置和獲取這五個值。
+
+可以寫入 ``metric`` 文件的關鍵詞和含義如下。
+
+ - none: 忽略水位
+ - free_mem_rate: 系統的自由內存率(千分比)。
+
+``interval`` 應以微秒爲單位寫入。
+
+schemes/<N>/stats/
+------------------
+
+DAMON統計每個方案被嘗試應用的區域的總數量和字節數,每個方案被成功應用的區域的兩個數字,以及
+超過配額限制的總數量。這些統計數據可用於在線分析或調整方案。
+
+可以通過讀取 ``stats`` 目錄下的文件(``nr_tried``, ``sz_tried``, ``nr_applied``,
+``sz_applied``, 和 ``qt_exceeds``))分別檢索這些統計數據。這些文件不是實時更新的,所以
+你應該要求DAMON sysfs接口通過在相關的 ``kdamonds/<N>/state`` 文件中寫入一個特殊的關鍵字
+``update_schemes_stats`` 來更新統計信息的文件內容。
+
+schemes/<N>/tried_regions/
+--------------------------
+
+當一個特殊的關鍵字 ``update_schemes_tried_regions`` 被寫入相關的 ``kdamonds/<N>/state``
+文件時,DAMON會在這個目錄下創建從 ``0`` 開始命名的整數目錄。每個目錄包含的文件暴露了關於每個
+內存區域的詳細信息,在下一個 :ref:`聚集區間 <sysfs_monitoring_attrs>`,相應的方案的 ``動作``
+已經嘗試在這個目錄下應用。這些信息包括地址範圍、``nr_accesses`` 以及區域的 ``年齡`` 。
+
+當另一個特殊的關鍵字 ``clear_schemes_tried_regions`` 被寫入相關的 ``kdamonds/<N>/state``
+文件時,這些目錄將被刪除。
+
+tried_regions/<N>/
+------------------
+
+在每個區域目錄中,你會發現四個文件(``start``, ``end``, ``nr_accesses``, and ``age``)。
+讀取這些文件將顯示相應的基於DAMON的操作方案 ``動作`` 試圖應用的區域的開始和結束地址、``nr_accesses``
+和 ``年齡`` 。
+
+用例
+~~~~
+
+下面的命令應用了一個方案:”如果一個大小爲[4KiB, 8KiB]的內存區域在[10, 20]的聚合時間間隔內
+顯示出每一個聚合時間間隔[0, 5]的訪問量,請分頁該區域。對於分頁,每秒最多隻能使用10ms,而且每
+秒分頁不能超過1GiB。在這一限制下,首先分頁出具有較長年齡的內存區域。另外,每5秒鐘檢查一次系統
+的可用內存率,當可用內存率低於50%時開始監測和分頁,但如果可用內存率大於60%,或低於30%,則停
+止監測。“ ::
+
+    # cd <sysfs>/kernel/mm/damon/admin
+    # # populate directories
+    # echo 1 > kdamonds/nr_kdamonds; echo 1 > kdamonds/0/contexts/nr_contexts;
+    # echo 1 > kdamonds/0/contexts/0/schemes/nr_schemes
+    # cd kdamonds/0/contexts/0/schemes/0
+    # # set the basic access pattern and the action
+    # echo 4096 > access_pattern/sz/min
+    # echo 8192 > access_pattern/sz/max
+    # echo 0 > access_pattern/nr_accesses/min
+    # echo 5 > access_pattern/nr_accesses/max
+    # echo 10 > access_pattern/age/min
+    # echo 20 > access_pattern/age/max
+    # echo pageout > action
+    # # set quotas
+    # echo 10 > quotas/ms
+    # echo $((1024*1024*1024)) > quotas/bytes
+    # echo 1000 > quotas/reset_interval_ms
+    # # set watermark
+    # echo free_mem_rate > watermarks/metric
+    # echo 5000000 > watermarks/interval_us
+    # echo 600 > watermarks/high
+    # echo 500 > watermarks/mid
+    # echo 300 > watermarks/low
+
+請注意,我們強烈建議使用用戶空間的工具,如 `damo <https://github.com/awslabs/damo>`_ ,
+而不是像上面那樣手動讀寫文件。以上只是一個例子。
+
+debugfs接口
+===========
+
+.. note::
+
+  DAMON debugfs接口將在下一個LTS內核發佈後被移除,所以用戶應該轉移到
+  :ref:`sysfs接口<sysfs_interface>`。
+
+DAMON導出了八個文件, ``attrs``, ``target_ids``, ``init_regions``,
+``schemes``, ``monitor_on``, ``kdamond_pid``, ``mk_contexts`` 和
+``rm_contexts`` under its debugfs directory, ``<debugfs>/damon/``.
+
+
+屬性
+----
+
+用戶可以通過讀取和寫入 ``attrs`` 文件獲得和設置 ``採樣間隔`` 、 ``聚集間隔`` 、 ``更新間隔``
+以及監測目標區域的最小/最大數量。要詳細瞭解監測屬性,請參考 `:doc:/mm/damon/design` 。例如,
+下面的命令將這些值設置爲5ms、100ms、1000ms、10和1000,然後再次檢查::
+
+    # cd <debugfs>/damon
+    # echo 5000 100000 1000000 10 1000 > attrs
+    # cat attrs
+    5000 100000 1000000 10 1000
+
+
+目標ID
+------
+
+一些類型的地址空間支持多個監測目標。例如,虛擬內存地址空間的監測可以有多個進程作爲監測目標。用戶
+可以通過寫入目標的相關id值來設置目標,並通過讀取 ``target_ids`` 文件來獲得當前目標的id。在監
+測虛擬地址空間的情況下,這些值應該是監測目標進程的pid。例如,下面的命令將pid爲42和4242的進程設
+爲監測目標,並再次檢查::
+
+    # cd <debugfs>/damon
+    # echo 42 4242 > target_ids
+    # cat target_ids
+    42 4242
+
+用戶還可以通過在文件中寫入一個特殊的關鍵字 "paddr\n" 來監測系統的物理內存地址空間。因爲物理地
+址空間監測不支持多個目標,讀取文件會顯示一個假值,即 ``42`` ,如下圖所示::
+
+    # cd <debugfs>/damon
+    # echo paddr > target_ids
+    # cat target_ids
+    42
+
+請注意,設置目標ID並不啓動監測。
+
+
+初始監測目標區域
+----------------
+
+在虛擬地址空間監測的情況下,DAMON自動設置和更新監測的目標區域,這樣就可以覆蓋目標進程的整個
+內存映射。然而,用戶可能希望將監測區域限制在特定的地址範圍內,如堆、棧或特定的文件映射區域。
+或者,一些用戶可以知道他們工作負載的初始訪問模式,因此希望爲“自適應區域調整”設置最佳初始區域。
+
+相比之下,DAMON在物理內存監測的情況下不會自動設置和更新監測目標區域。因此,用戶應該自己設置
+監測目標區域。
+
+在這種情況下,用戶可以通過在 ``init_regions`` 文件中寫入適當的值,明確地設置他們想要的初
+始監測目標區域。輸入應該是一個由三個整數組成的隊列,用空格隔開,代表一個區域的形式如下::
+
+    <target idx> <start address> <end address>
+
+目標idx應該是 ``target_ids`` 文件中目標的索引,從 ``0`` 開始,區域應該按照地址順序傳遞。
+例如,下面的命令將設置幾個地址範圍, ``1-100`` 和 ``100-200`` 作爲pid 42的初始監測目標
+區域,這是 ``target_ids`` 中的第一個(索引 ``0`` ),另外幾個地址範圍, ``20-40`` 和
+``50-100`` 作爲pid 4242的地址,這是 ``target_ids`` 中的第二個(索引 ``1`` )::
+
+    # cd <debugfs>/damon
+    # cat target_ids
+    42 4242
+    # echo "0   1       100 \
+            0   100     200 \
+            1   20      40  \
+            1   50      100" > init_regions
+
+請注意,這只是設置了初始的監測目標區域。在虛擬內存監測的情況下,DAMON會在一個 ``更新間隔``
+後自動更新區域的邊界。因此,在這種情況下,如果用戶不希望更新的話,應該把 ``更新間隔`` 設
+置得足夠大。
+
+
+方案
+----
+
+對於通常的基於DAMON的數據訪問感知的內存管理優化,用戶只是希望系統對特定訪問模式的內存區域應用內
+存管理操作。DAMON從用戶那裏接收這種形式化的操作方案,並將這些方案應用到目標進程中。
+
+用戶可以通過讀取和寫入 ``scheme`` debugfs文件來獲得和設置這些方案。讀取該文件還可以顯示每個
+方案的統計數據。在文件中,每一個方案都應該在每一行中以下列形式表示出來::
+
+    <target access pattern> <action> <quota> <watermarks>
+
+你可以通過簡單地在文件中寫入一個空字符串來禁用方案。
+
+目標訪問模式
+~~~~~~~~~~~~
+
+``<目標訪問模式>`` 是由三個範圍構成的,形式如下::
+
+    min-size max-size min-acc max-acc min-age max-age
+
+具體來說,區域大小的字節數( `min-size` 和 `max-size` ),訪問頻率的每聚合區間的監測訪問次
+數( `min-acc` 和 `max-acc` ),區域年齡的聚合區間數( `min-age` 和 `max-age` )都被指定。
+請注意,這些範圍是封閉區間。
+
+動作
+~~~~
+
+``<action>`` 是一個預定義的內存管理動作的整數,DAMON將應用於具有目標訪問模式的區域。支持
+的數字和它們的含義如下::
+
+ - 0: Call ``madvise()`` for the region with ``MADV_WILLNEED``
+ - 1: Call ``madvise()`` for the region with ``MADV_COLD``
+ - 2: Call ``madvise()`` for the region with ``MADV_PAGEOUT``
+ - 3: Call ``madvise()`` for the region with ``MADV_HUGEPAGE``
+ - 4: Call ``madvise()`` for the region with ``MADV_NOHUGEPAGE``
+ - 5: Do nothing but count the statistics
+
+配額
+~~~~
+
+每個 ``動作`` 的最佳 ``目標訪問模式`` 取決於工作負載,所以不容易找到。更糟糕的是,將某個
+動作的方案設置得過於激進會導致嚴重的開銷。爲了避免這種開銷,用戶可以通過下面表格中的 ``<quota>``
+來限制方案的時間和大小配額::
+
+    <ms> <sz> <reset interval> <priority weights>
+
+這使得DAMON在 ``<reset interval>`` 毫秒內,儘量只用 ``<ms>`` 毫秒的時間對 ``目標訪
+問模式`` 的內存區域應用動作,並在 ``<reset interval>`` 內只對最多<sz>字節的內存區域應
+用動作。將 ``<ms>`` 和 ``<sz>`` 都設置爲零,可以禁用配額限制。
+
+當預計超過配額限制時,DAMON會根據 ``目標訪問模式`` 的大小、訪問頻率和年齡,對發現的內存
+區域進行優先排序。爲了實現個性化的優先級,用戶可以在 ``<優先級權重>`` 中設置這三個屬性的
+權重,具體形式如下::
+
+    <size weight> <access frequency weight> <age weight>
+
+水位
+~~~~
+
+有些方案需要根據系統特定指標的當前值來運行,如自由內存比率。對於這種情況,用戶可以爲該條
+件指定水位。::
+
+    <metric> <check interval> <high mark> <middle mark> <low mark>
+
+``<metric>`` 是一個預定義的整數,用於要檢查的度量。支持的數字和它們的含義如下。
+
+ - 0: 忽視水位
+ - 1: 系統空閒內存率 (千分比)
+
+每隔 ``<檢查間隔>`` 微秒檢查一次公制的值。
+
+如果該值高於 ``<高標>`` 或低於 ``<低標>`` ,該方案被停用。如果該值低於 ``<中標>`` ,
+該方案將被激活。
+
+統計數據
+~~~~~~~~
+
+它還統計每個方案被嘗試應用的區域的總數量和字節數,每個方案被成功應用的區域的兩個數量,以
+及超過配額限制的總數量。這些統計數據可用於在線分析或調整方案。
+
+統計數據可以通過讀取方案文件來顯示。讀取該文件將顯示你在每一行中輸入的每個 ``方案`` ,
+統計的五個數字將被加在每一行的末尾。
+
+例子
+~~~~
+
+下面的命令應用了一個方案:”如果一個大小爲[4KiB, 8KiB]的內存區域在[10, 20]的聚合時間
+間隔內顯示出每一個聚合時間間隔[0, 5]的訪問量,請分頁出該區域。對於分頁,每秒最多隻能使
+用10ms,而且每秒分頁不能超過1GiB。在這一限制下,首先分頁出具有較長年齡的內存區域。另外,
+每5秒鐘檢查一次系統的可用內存率,當可用內存率低於50%時開始監測和分頁,但如果可用內存率
+大於60%,或低於30%,則停止監測“::
+
+    # cd <debugfs>/damon
+    # scheme="4096 8192  0 5    10 20    2"  # target access pattern and action
+    # scheme+=" 10 $((1024*1024*1024)) 1000" # quotas
+    # scheme+=" 0 0 100"                     # prioritization weights
+    # scheme+=" 1 5000000 600 500 300"       # watermarks
+    # echo "$scheme" > schemes
+
+
+開關
+----
+
+除非你明確地啓動監測,否則如上所述的文件設置不會產生效果。你可以通過寫入和讀取 ``monitor_on``
+文件來啓動、停止和檢查監測的當前狀態。寫入 ``on`` 該文件可以啓動對有屬性的目標的監測。寫入
+``off`` 該文件則停止這些目標。如果每個目標進程被終止,DAMON也會停止。下面的示例命令開啓、關
+閉和檢查DAMON的狀態::
+
+    # cd <debugfs>/damon
+    # echo on > monitor_on
+    # echo off > monitor_on
+    # cat monitor_on
+    off
+
+請注意,當監測開啓時,你不能寫到上述的debugfs文件。如果你在DAMON運行時寫到這些文件,將會返
+回一個錯誤代碼,如 ``-EBUSY`` 。
+
+
+監測線程PID
+-----------
+
+DAMON通過一個叫做kdamond的內核線程來進行請求監測。你可以通過讀取 ``kdamond_pid`` 文件獲
+得該線程的 ``pid`` 。當監測被 ``關閉`` 時,讀取該文件不會返回任何信息::
+
+    # cd <debugfs>/damon
+    # cat monitor_on
+    off
+    # cat kdamond_pid
+    none
+    # echo on > monitor_on
+    # cat kdamond_pid
+    18594
+
+
+使用多個監測線程
+----------------
+
+每個監測上下文都會創建一個 ``kdamond`` 線程。你可以使用 ``mk_contexts`` 和 ``rm_contexts``
+文件爲多個 ``kdamond`` 需要的用例創建和刪除監測上下文。
+
+將新上下文的名稱寫入 ``mk_contexts`` 文件,在 ``DAMON debugfs`` 目錄上創建一個該名稱的目錄。
+該目錄將有該上下文的 ``DAMON debugfs`` 文件::
+
+    # cd <debugfs>/damon
+    # ls foo
+    # ls: cannot access 'foo': No such file or directory
+    # echo foo > mk_contexts
+    # ls foo
+    # attrs  init_regions  kdamond_pid  schemes  target_ids
+
+如果不再需要上下文,你可以通過把上下文的名字放到 ``rm_contexts`` 文件中來刪除它和相應的目錄::
+
+    # echo foo > rm_contexts
+    # ls foo
+    # ls: cannot access 'foo': No such file or directory
+
+注意, ``mk_contexts`` 、 ``rm_contexts`` 和 ``monitor_on`` 文件只在根目錄下。
+
+
+監測結果的監測點
+================
+
+DAMON通過一個tracepoint ``damon:damon_aggregated`` 提供監測結果.  當監測開啓時,你可
+以記錄追蹤點事件,並使用追蹤點支持工具如perf顯示結果。比如說::
+
+    # echo on > monitor_on
+    # perf record -e damon:damon_aggregated &
+    # sleep 5
+    # kill 9 $(pidof perf)
+    # echo off > monitor_on
+    # perf script
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/index.rst b/Documentation/translations/zh_TW/admin-guide/mm/index.rst
new file mode 100644
index 000000000000..917559614a1f
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/index.rst
@@ -0,0 +1,52 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original:   Documentation/admin-guide/mm/index.rst
+
+:翻譯:
+
+  徐鑫 xu xin <xu.xin16@zte.com.cn>
+
+
+========
+內存管理
+========
+
+Linux內存管理子系統,顧名思義,是負責系統中的內存管理。它包括了虛擬內存與請求
+分頁的實現,內核內部結構和用戶空間程序的內存分配、將文件映射到進程地址空間以
+及許多其他很酷的事情。
+
+Linux內存管理是一個具有許多可配置設置的複雜系統, 且這些設置中的大多數都可以通
+過 ``/proc`` 文件系統獲得,並且可以使用 ``sysctl`` 進行查詢和調整。這些API接
+口被描述在Documentation/admin-guide/sysctl/vm.rst文件和 `man 5 proc`_ 中。
+
+.. _man 5 proc: http://man7.org/linux/man-pages/man5/proc.5.html
+
+Linux內存管理有它自己的術語,如果你還不熟悉它,請考慮閱讀下面參考:
+Documentation/admin-guide/mm/concepts.rst.
+
+在此目錄下,我們詳細描述瞭如何與Linux內存管理中的各種機制交互。
+
+.. toctree::
+   :maxdepth: 1
+
+   damon/index
+   ksm
+
+Todolist:
+* concepts
+* cma_debugfs
+* hugetlbpage
+* idle_page_tracking
+* memory-hotplug
+* nommu-mmap
+* numa_memory_policy
+* numaperf
+* pagemap
+* soft-dirty
+* swap_numa
+* transhuge
+* userfaultfd
+* zswap
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/ksm.rst b/Documentation/translations/zh_TW/admin-guide/mm/ksm.rst
new file mode 100644
index 000000000000..3b401c09e7bf
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/ksm.rst
@@ -0,0 +1,201 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/ksm.rst
+
+:翻譯:
+
+  徐鑫 xu xin <xu.xin16@zte.com.cn>
+
+
+============
+內核同頁合併
+============
+
+
+概述
+====
+
+KSM是一種能節省內存的數據去重功能,由CONFIG_KSM=y啓用,並在2.6.32版本時被添
+加到Linux內核。詳見 ``mm/ksm.c`` 的實現,以及http://lwn.net/Articles/306704
+和https://lwn.net/Articles/330589
+
+KSM最初目的是爲了與KVM(即著名的內核共享內存)一起使用而開發的,通過共享虛擬機
+之間的公共數據,將更多虛擬機放入物理內存。但它對於任何會生成多個相同數據實例的
+應用程序都是很有用的。
+
+KSM的守護進程ksmd會定期掃描那些已註冊的用戶內存區域,查找內容相同的頁面,這些
+頁面可以被單個寫保護頁面替換(如果進程以後想要更新其內容,將自動複製)。使用:
+引用:`sysfs intraface  <ksm_sysfs>` 接口來配置KSM守護程序在單個過程中所掃描的頁
+數以及兩個過程之間的間隔時間。
+
+KSM只合並匿名(私有)頁面,從不合並頁緩存(文件)頁面。KSM的合併頁面最初只能被
+鎖定在內核內存中,但現在可以就像其他用戶頁面一樣被換出(但當它們被交換回來時共
+享會被破壞: ksmd必須重新發現它們的身份並再次合併)。
+
+以madvise控制KSM
+================
+
+KSM僅在特定的地址空間區域時運行,即應用程序通過使用如下所示的madvise(2)系統調
+用來請求某塊地址成爲可能的合併候選者的地址空間::
+
+    int madvise(addr, length, MADV_MERGEABLE)
+
+應用程序當然也可以通過調用::
+
+    int madvise(addr, length, MADV_UNMERGEABLE)
+
+來取消該請求,並恢復爲非共享頁面:此時KSM將去除合併在該範圍內的任何合併頁。注意:
+這個去除合併的調用可能突然需要的內存量超過實際可用的內存量-那麼可能會出現EAGAIN
+失敗,但更可能會喚醒OOM killer。
+
+如果KSM未被配置到正在運行的內核中,則madvise MADV_MERGEABLE 和 MADV_UNMERGEABLE
+的調用只會以EINVAL 失敗。如果正在運行的內核是用CONFIG_KSM=y方式構建的,那麼這些
+調用通常會成功:即使KSM守護程序當前沒有運行,MADV_MERGEABLE 仍然會在KSM守護程序
+啓動時註冊範圍,即使該範圍不能包含KSM實際可以合併的任何頁面,即使MADV_UNMERGEABLE
+應用於從未標記爲MADV_MERGEABLE的範圍。
+
+如果一塊內存區域必須被拆分爲至少一個新的MADV_MERGEABLE區域或MADV_UNMERGEABLE區域,
+當該進程將超過 ``vm.max_map_count`` 的設定,則madvise可能返回ENOMEM。(請參閱文檔
+Documentation/admin-guide/sysctl/vm.rst)。
+
+與其他madvise調用一樣,它們在用戶地址空間的映射區域上使用:如果指定的範圍包含未
+映射的間隙(儘管在中間的映射區域工作),它們將報告ENOMEM,如果沒有足夠的內存用於
+內部結構,則可能會因EAGAIN而失敗。
+
+KSM守護進程sysfs接口
+====================
+
+KSM守護進程可以由``/sys/kernel/mm/ksm/`` 中的sysfs文件控制,所有人都可以讀取,但
+只能由root用戶寫入。各接口解釋如下:
+
+
+pages_to_scan
+        ksmd進程進入睡眠前要掃描的頁數。
+        例如, ``echo 100 > /sys/kernel/mm/ksm/pages_to_scan``
+
+        默認值:100(該值被選擇用於演示目的)
+
+sleep_millisecs
+        ksmd在下次掃描前應休眠多少毫秒
+        例如, ``echo 20 > /sys/kernel/mm/ksm/sleep_millisecs``
+
+        默認值:20(該值被選擇用於演示目的)
+
+merge_across_nodes
+        指定是否可以合併來自不同NUMA節點的頁面。當設置爲0時,ksm僅合併在物理上位
+        於同一NUMA節點的內存區域中的頁面。這降低了訪問共享頁面的延遲。在有明顯的
+        NUMA距離上,具有更多節點的系統可能受益於設置該值爲0時的更低延遲。而對於
+        需要對內存使用量最小化的較小系統來說,設置該值爲1(默認設置)則可能會受
+        益於更大共享頁面。在決定使用哪種設置之前,您可能希望比較系統在每種設置下
+        的性能。 ``merge_across_nodes`` 僅當系統中沒有ksm共享頁面時,才能被更改設
+        置:首先將接口`run` 設置爲2從而對頁進行去合併,然後在修改
+        ``merge_across_nodes`` 後再將‘run’又設置爲1,以根據新設置來重新合併。
+
+        默認值:1(如早期的發佈版本一樣合併跨站點)
+
+run
+        * 設置爲0可停止ksmd運行,但保留合併頁面,
+        * 設置爲1可運行ksmd,例如, ``echo 1 > /sys/kernel/mm/ksm/run`` ,
+        * 設置爲2可停止ksmd運行,並且對所有目前已合併的頁進行去合併,但保留可合併
+          區域以供下次運行。
+
+        默認值:0(必須設置爲1才能激活KSM,除非禁用了CONFIG_SYSFS)
+
+use_zero_pages
+        指定是否應當特殊處理空頁(即那些僅含zero的已分配頁)。當該值設置爲1時,
+        空頁與內核零頁合併,而不是像通常情況下那樣空頁自身彼此合併。這可以根據
+        工作負載的不同,在具有着色零頁的架構上可以提高性能。啓用此設置時應小心,
+        因爲它可能會降低某些工作負載的KSM性能,比如,當待合併的候選頁面的校驗和
+        與空頁面的校驗和恰好匹配的時候。此設置可隨時更改,僅對那些更改後再合併
+        的頁面有效。
+
+        默認值:0(如同早期版本的KSM正常表現)
+
+max_page_sharing
+        單個KSM頁面允許的最大共享站點數。這將強制執行重複數據消除限制,以避免涉
+        及遍歷共享KSM頁面的虛擬映射的虛擬內存操作的高延遲。最小值爲2,因爲新創
+        建的KSM頁面將至少有兩個共享者。該值越高,KSM合併內存的速度越快,去重
+        因子也越高,但是對於任何給定的KSM頁面,虛擬映射的最壞情況遍歷的速度也會
+        越慢。減慢了這種遍歷速度就意味着在交換、壓縮、NUMA平衡和頁面遷移期間,
+        某些虛擬內存操作將有更高的延遲,從而降低這些虛擬內存操作調用者的響應能力。
+        其他任務如果不涉及執行虛擬映射遍歷的VM操作,其任務調度延遲不受此參數的影
+        響,因爲這些遍歷本身是調度友好的。
+
+stable_node_chains_prune_millisecs
+        指定KSM檢查特定頁面的元數據的頻率(即那些達到過時信息數據去重限制標準的
+        頁面)單位是毫秒。較小的毫秒值將以更低的延遲來釋放KSM元數據,但它們將使
+        ksmd在掃描期間使用更多CPU。如果還沒有一個KSM頁面達到 ``max_page_sharing``
+        標準,那就沒有什麼用。
+
+KSM與MADV_MERGEABLE的工作有效性體現於 ``/sys/kernel/mm/ksm/`` 路徑下的接口:
+
+pages_shared
+        表示多少共享頁正在被使用
+pages_sharing
+        表示還有多少站點正在共享這些共享頁,即節省了多少
+pages_unshared
+        表示有多少頁是唯一的,但被反覆檢查以進行合併
+pages_volatile
+        表示有多少頁因變化太快而無法放在tree中
+full_scans
+        表示所有可合併區域已掃描多少次
+stable_node_chains
+        達到 ``max_page_sharing`` 限制的KSM頁數
+stable_node_dups
+        重複的KSM頁數
+
+比值 ``pages_sharing/pages_shared`` 的最大值受限制於 ``max_page_sharing``
+的設定。要想增加該比值,則相應地要增加 ``max_page_sharing`` 的值。
+
+監測KSM的收益
+=============
+
+KSM可以通過合併相同的頁面來節省內存,但也會消耗額外的內存,因爲它需要生成一些rmap_items
+來保存每個掃描頁面的簡要rmap信息。其中有些頁面可能會被合併,但有些頁面在被檢查幾次
+後可能無法被合併,這些都是無益的內存消耗。
+
+1) 如何確定KSM在全系統範圍內是節省內存還是消耗內存?這裏有一個簡單的近似計算方法供參考::
+
+       general_profit =~ pages_sharing * sizeof(page) - (all_rmap_items) *
+                         sizeof(rmap_item);
+
+   其中all_rmap_items可以通過對 ``pages_sharing`` 、 ``pages_shared`` 、 ``pages_unshared``
+   和 ``pages_volatile`` 的求和而輕鬆獲得。
+
+2) 單一進程中KSM的收益也可以通過以下近似的計算得到::
+
+       process_profit =~ ksm_merging_pages * sizeof(page) -
+                         ksm_rmap_items * sizeof(rmap_item).
+
+   其中ksm_merging_pages顯示在 ``/proc/<pid>/`` 目錄下,而ksm_rmap_items
+   顯示在 ``/proc/<pid>/ksm_stat`` 。
+
+從應用的角度來看, ``ksm_rmap_items`` 和 ``ksm_merging_pages`` 的高比例意
+味着不好的madvise-applied策略,所以開發者或管理員必須重新考慮如何改變madvis策
+略。舉個例子供參考,一個頁面的大小通常是4K,而rmap_item的大小在32位CPU架構上分
+別是32B,在64位CPU架構上是64B。所以如果 ``ksm_rmap_items/ksm_merging_pages``
+的比例在64位CPU上超過64,或者在32位CPU上超過128,那麼應用程序的madvise策略應
+該被放棄,因爲ksm收益大約爲零或負值。
+
+監控KSM事件
+===========
+
+在/proc/vmstat中有一些計數器,可以用來監控KSM事件。KSM可能有助於節省內存,這是
+一種權衡,因爲它可能會在KSM COW或複製中的交換上遭受延遲。這些事件可以幫助用戶評估
+是否或如何使用KSM。例如,如果cow_ksm增加得太快,用戶可以減少madvise(, , MADV_MERGEABLE)
+的範圍。
+
+cow_ksm
+        在每次KSM頁面觸發寫時拷貝(COW)時都會被遞增,當用戶試圖寫入KSM頁面時,
+        我們必須做一個拷貝。
+
+ksm_swpin_copy
+        在換入時,每次KSM頁被複制時都會被遞增。請注意,KSM頁在換入時可能會被複
+        制,因爲do_swap_page()不能做所有的鎖,而需要重組一個跨anon_vma的KSM頁。
+
+--
+Izik Eidus,
+Hugh Dickins, 2009年11月17日。
+
diff --git a/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst b/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst
index 27638e199f13..fe5a5a07d51a 100644
--- a/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst
+++ b/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst
@@ -1,13 +1,6 @@
 .. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0)
-..
-   If you want to distribute this text under CC-BY-4.0 only, please use 'The
-   Linux kernel developers' for author attribution and link this as source:
-   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/reporting-issues.rst
-..
-   Note: Only the content of this RST file as found in the Linux kernel sources
-   is available under CC-BY-4.0, as versions of this text that were processed
-   (for example by the kernel's build system) might contain content taken from
-   files which use a more restrictive license.
+.. See the bottom of this file for additional redistribution information.
+
 
 .. include:: ../disclaimer-zh_TW.rst
 
@@ -16,7 +9,7 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 
 報告問題
@@ -26,14 +19,16 @@
 簡明指南(亦即 太長不看)
 ==========================
 
-您面臨的是否爲同系列穩定版或長期支持內核的普通內核的回歸?是否仍然受支持?
+您面臨的是否爲同系列穩定版或長期支持內核的普通內核的迴歸?是否仍然受支持?
 請搜索 `LKML內核郵件列表 <https://lore.kernel.org/lkml/>`_ 和
 `Linux穩定版郵件列表 <https://lore.kernel.org/stable/>`_ 存檔中匹配的報告並
 加入討論。如果找不到匹配的報告,請安裝該系列的最新版本。如果它仍然出現問題,
-報告給穩定版郵件列表(stable@vger.kernel.org)。
+請報告給穩定版郵件列表(stable@vger.kernel.org)並抄送回歸郵件列表
+(regressions@lists.linux.dev);理想情況下,還可以抄送維護者和相關子系統的
+郵件列表。
 
 在所有其他情況下,請儘可能猜測是哪個內核部分導致了問題。查看MAINTAINERS文件,
-了解開發人員希望如何得知問題,大多數情況下,報告問題都是通過電子郵件和抄送
+瞭解開發人員希望如何得知問題,大多數情況下,報告問題都是通過電子郵件和抄送
 相關郵件列表進行的。檢查報告目的地的存檔中是否已有匹配的報告;也請搜索
 `LKML <https://lore.kernel.org/lkml/>`_ 和網絡。如果找不到可加入的討論,請
 安裝 `最新的主線內核 <https://kernel.org/>`_ 。如果仍存在問題,請發送報告。
@@ -45,21 +40,22 @@
 
 **通用提醒** :當安裝和測試上述內核時,請確保它是普通的(即:沒有補丁,也沒
 有使用附加模塊)。還要確保它是在一個正常的環境中構建和運行,並且在問題發生
-之前沒有被汙染(tainted)。
+之前沒有被污染(tainted)。
 
-在編寫報告時,要涵蓋與問題相關的所有信息,如使用的內核和發行版。在碰見回歸時,
-嘗試給出引入它的更改的提交ID,二分可以找到它。如果您同時面臨Linux內核的多個
-問題,請分別報告每個問題。
+當你同時面臨Linux內核的多個問題時,請分別報告。在編寫報告時,要涵蓋與問題
+相關的所有信息,如使用的內核和發行版。如果碰見迴歸,請把報告抄送回歸郵件列表
+(regressions@lists.linux.dev)。也請試試用二分法找出源頭;如果成功找到,請
+在報告中寫上它的提交ID並抄送sign-off-by鏈中的所有人。
 
 一旦報告發出,請回答任何出現的問題,並儘可能地提供幫助。這包括通過不時重新
-測試新版本並發送狀態更新來推動進展。
+測試新版本併發送狀態更新來推動進展。
 
 
 如何向內核維護人員報告問題的逐步指南
 =====================================
 
-上面的簡明指南概述了如何向Linux內核開發人員報告問題。對於已經熟悉向自由和開
-源軟體(FLOSS)項目報告問題的人來說,這可能是他們所需要的全部內容。對於其他
+上面的簡明指南概述瞭如何向Linux內核開發人員報告問題。對於已經熟悉向自由和開
+源軟件(FLOSS)項目報告問題的人來說,這可能是他們所需要的全部內容。對於其他
 人,本部分更爲詳細,並一步一步地描述。爲了便於閱讀,它仍然儘量簡潔,並省略
 了許多細節;這些在逐步指南後的參考章節中進行了描述,該章節更詳細地解釋了每
 個步驟。
@@ -68,16 +64,16 @@
 儘早意識到看起來像Linux內核毛病的問題可能實際上是由其他原因引起的。這些步驟
 可以確保你最終不會覺得在這一過程中投入的時間是浪費:
 
- * 您是否面臨硬體或軟體供應商提供的Linux內核的問題?那麼基本上您最好停止閱讀
+ * 您是否面臨硬件或軟件供應商提供的Linux內核的問題?那麼基本上您最好停止閱讀
    本文檔,轉而向您的供應商報告問題,除非您願意自己安裝最新的Linux版本。尋找
    和解決問題往往需要後者。
 
- * 使用您喜愛的網絡搜尋引擎對現有報告進行粗略搜索;此外,請檢查
+ * 使用您喜愛的網絡搜索引擎對現有報告進行粗略搜索;此外,請檢查
    `Linux內核郵件列表(LKML) <https://lore.kernel.org/lkml/>`_ 的存檔。如果
    找到匹配的報告,請加入討論而不是發送新報告。
 
- * 看看你正在處理的問題是否爲回歸問題、安全問題或非常嚴重的問題:這些都是需
-   要在接下來的一些步驟中特別處理的「高優先級問題」。
+ * 看看你正在處理的問題是否爲迴歸問題、安全問題或非常嚴重的問題:這些都是需
+   要在接下來的一些步驟中特別處理的“高優先級問題”。
 
  * 確保不是內核環境導致了您面臨的問題。
 
@@ -86,15 +82,15 @@
  * 確保您的系統不會通過動態構建額外的內核模塊來增強其內核,像DKMS這樣的解決
    方案可能在您不知情的情況下就在本地進行了這樣的工作。
 
- * 當問題發生時,檢查您的內核是否被「汙染」,因爲使內核設置這個標誌的事件可能
+ * 當問題發生時,檢查您的內核是否被“污染”,因爲使內核設置這個標誌的事件可能
    會導致您面臨的問題。
 
  * 粗略地寫下如何重現這個問題。如果您同時處理多個問題,請爲每個問題單獨寫注
    釋,並確保它們在新啓動的系統上獨立出現。這是必要的,因爲每個問題都需要分
    別報告給內核開發人員,除非它們嚴重糾纏在一起。
 
- * 如果您正面臨穩定版或長期支持版本線的回歸(例如從5.10.4更新到5.10.5時出現
-   故障),請查看後文「報告穩定版和長期支持內核線的回歸」小節。
+ * 如果您正面臨穩定版或長期支持版本線的迴歸(例如從5.10.4更新到5.10.5時出現
+   故障),請查看後文“報告穩定版和長期支持內核線的迴歸”小節。
 
  * 定位可能引起問題的驅動程序或內核子系統。找出其開發人員期望的報告的方式和
    位置。注意:大多數情況下不會是 bugzilla.kernel.org,因爲問題通常需要通
@@ -105,61 +101,62 @@
 
 在完成這些準備之後,你將進入主要部分:
 
- * 除非您已經在運行最新的「主線」Linux內核,否則最好在報告流程前安裝它。在某些
-   情況下,使用最新的「穩定版」Linux進行測試和報告也是可以接受的替代方案;在
+ * 除非您已經在運行最新的“主線”Linux內核,否則最好在報告流程前安裝它。在某些
+   情況下,使用最新的“穩定版”Linux進行測試和報告也是可以接受的替代方案;在
    合併窗口期間,這實際上可能是最好的方法,但在開發階段最好還是暫停幾天。無論
-   你選擇什麼版本,最好使用「普通」構建。忽略這些建議會大大增加您的報告被拒絕
+   你選擇什麼版本,最好使用“普通”構建。忽略這些建議會大大增加您的報告被拒絕
    或忽略的風險。
 
- * 確保您剛剛安裝的內核在運行時不會「汙染」自己。
+ * 確保您剛剛安裝的內核在運行時不會“污染”自己。
 
  * 在您剛剛安裝的內核中復現這個問題。如果它沒有出現,請查看下方只發生在
    穩定版和長期支持內核的問題的說明。
 
- * 優化你的筆記:試著找到並寫出最直接的復現問題的方法。確保最終結果包含所有
+ * 優化你的筆記:試着找到並寫出最直接的復現問題的方法。確保最終結果包含所有
    重要的細節,同時讓第一次聽說的人容易閱讀和理解。如果您在此過程中學到了一
    些東西,請考慮再次搜索關於該問題的現有報告。
 
- * 如果失敗涉及「panic」、「Oops」、「warning」或「BUG」,請考慮解碼內核日誌以查找觸
+ * 如果失敗涉及“panic”、“Oops”、“warning”或“BUG”,請考慮解碼內核日誌以查找觸
    發錯誤的代碼行。
 
- * 如果您的問題是回歸問題,請儘可能縮小引入問題時的範圍。
+ * 如果您的問題是迴歸問題,請儘可能縮小引入問題時的範圍。
 
  * 通過詳細描述問題來開始編寫報告。記得包括以下條目:您爲復現而安裝的最新內
    核版本、使用的Linux發行版以及關於如何復現該問題的說明。如果可能,將內核
-   構建配置(.config)和 ``dmesg`` 的輸出放在網上的某個地方,並連結到它。包
+   構建配置(.config)和 ``dmesg`` 的輸出放在網上的某個地方,並鏈接到它。包
    含或上傳所有其他可能相關的信息,如Oops的輸出/截圖或來自 ``lspci`` 的輸出
    。一旦你寫完了這個主要部分,請在上方插入一個正常長度的段落快速概述問題和
    影響。再在此之上添加一個簡單描述問題的句子,以得到人們的閱讀。現在給出一
    個更短的描述性標題或主題。然後就可以像MAINTAINERS文件告訴你的那樣發送或
-   提交報告了,除非你在處理一個「高優先級問題」:它們需要按照下面「高優先級問
-   題的特殊處理」所述特別關照。
+   提交報告了,除非你在處理一個“高優先級問題”:它們需要按照下面“高優先級問
+   題的特殊處理”所述特別關照。
 
  * 等待別人的反應,繼續推進事情,直到你能夠接受這樣或那樣的結果。因此,請公
    開和及時地回應任何詢問。測試提出的修復。積極地測試:至少重新測試每個新主
    線版本的首個候選版本(RC),並報告你的結果。如果出現拖延,就友好地提醒一
-   下。如果你沒有得到任何幫助或者未能滿意,請試著自己幫助自己。
+   下。如果你沒有得到任何幫助或者未能滿意,請試着自己幫助自己。
 
 
-報告穩定版和長期支持內核線的回歸
+報告穩定版和長期支持內核線的迴歸
 ----------------------------------
 
-如果您發現了穩定版或長期支持內核版本線中的回歸問題並按上述流程跳到這裡,那麼
+如果您發現了穩定版或長期支持內核版本線中的迴歸問題並按上述流程跳到這裏,那麼
 請閱讀本小節。即例如您在從5.10.4更新到5.10.5時出現了問題(從5.9.15到5.10.5則
-不是)。開發人員希望儘快修復此類回歸,因此有一個簡化流程來報告它們:
+不是)。開發人員希望儘快修復此類迴歸,因此有一個簡化流程來報告它們:
 
  * 檢查內核開發人員是否仍然維護你關心的Linux內核版本線:去 `kernel.org 的首頁
-   <https://kernel.org/>`_ ,確保此特定版本線的最新版沒有「[EOL]」標記。
+   <https://kernel.org/>`_ ,確保此特定版本線的最新版沒有“[EOL]”標記。
 
  * 檢查 `Linux穩定版郵件列表 <https://lore.kernel.org/stable/>`_ 中的現有報告。
 
- * 從特定的版本線安裝最新版本作爲純淨內核。確保這個內核沒有被汙染,並且仍然
-   存在問題,因爲問題可能已經在那裡被修復了。如果您第一次發現供應商內核的問題,
+ * 從特定的版本線安裝最新版本作爲純淨內核。確保這個內核沒有被污染,並且仍然
+   存在問題,因爲問題可能已經在那裏被修復了。如果您第一次發現供應商內核的問題,
    請檢查已知最新版本的普通構建是否可以正常運行。
 
- * 向Linux穩定版郵件列表發送一個簡短的問題報告(stable@vger.kernel.org)。大致
-   描述問題,並解釋如何復現。講清楚首個出現問題的版本和最後一個工作正常的版本。
-   然後等待進一步的指示。
+ * 向Linux穩定版郵件列表發送一個簡短的問題報告(stable@vger.kernel.org)並抄送
+   Linux迴歸郵件列表(regressions@lists.linux.dev);如果你懷疑是由某子系統
+   引起的,請抄送其維護人員和子系統郵件列表。大致描述問題,並解釋如何復現。
+   講清楚首個出現問題的版本和最後一個工作正常的版本。然後等待進一步的指示。
 
 下面的參考章節部分詳細解釋了這些步驟中的每一步。
 
@@ -167,14 +164,14 @@
 報告只發生在較舊內核版本線的問題
 ----------------------------------
 
-若您嘗試了上述的最新主線內核,但未能在那裡復現問題,那麼本小節適用於您;以下
+若您嘗試了上述的最新主線內核,但未能在那裏復現問題,那麼本小節適用於您;以下
 流程有助於使問題在仍然支持的穩定版或長期支持版本線,或者定期基於最新穩定版或
 長期支持內核的供應商內核中得到修復。如果是這種情況,請執行以下步驟:
 
  * 請做好準備,接下來的幾個步驟可能無法在舊版本中解決問題:修復可能太大或太
-   冒險,無法移植到那裡。
+   冒險,無法移植到那裏。
 
- * 執行前節「報告穩定版和長期支持內核線的回歸」中的前三個步驟。
+ * 執行前節“報告穩定版和長期支持內核線的迴歸”中的前三個步驟。
 
  * 在Linux內核版本控制系統中搜索修復主線問題的更改,因爲它的提交消息可能會
    告訴你修復是否已經計劃好了支持。如果你沒有找到,搜索適當的郵件列表,尋找
@@ -219,14 +216,14 @@
 確保您使用的是上游Linux內核
 ----------------------------
 
-   *您是否面臨硬體或軟體供應商提供的Linux內核的問題?那麼基本上您最好停止閱
+   *您是否面臨硬件或軟件供應商提供的Linux內核的問題?那麼基本上您最好停止閱
    讀本文檔,轉而向您的供應商報告問題,除非您願意自己安裝最新的Linux版本。
    尋找和解決問題往往需要後者。*
 
-與大多數程式設計師一樣,Linux內核開發人員不喜歡花時間處理他們維護的原始碼中根本
-不會發生的問題的報告。這只會浪費每個人的時間,尤其是你的時間。不幸的是,當
+與大多數程序員一樣,Linux內核開發人員不喜歡花時間處理他們維護的源代碼中根本
+不會發生的問題的報告。這隻會浪費每個人的時間,尤其是你的時間。不幸的是,當
 涉及到內核時,這樣的情況很容易發生,並且常常導致雙方氣餒。這是因爲幾乎所有預
-裝在設備(台式機、筆記本電腦、智慧型手機、路由器等)上的Linux內核,以及大多數
+裝在設備(臺式機、筆記本電腦、智能手機、路由器等)上的Linux內核,以及大多數
 由Linux發行商提供的內核,都與由kernel.org發行的官方Linux內核相距甚遠:從Linux
 開發的角度來看,這些供應商提供的內核通常是古老的或者經過了大量修改,通常兩點
 兼具。
@@ -235,19 +232,19 @@
 可能已經由Linux內核開發人員在數月或數年前修復;此外,供應商的修改和增強可能
 會導致您面臨的問題,即使它們看起來很小或者完全不相關。這就是爲什麼您應該向
 供應商報告這些內核的問題。它的開發者應該查看報告,如果它是一個上游問題,直接
-於上游修復或將報告轉發到那裡。在實踐中,這有時行不通。因此,您可能需要考慮
+於上游修復或將報告轉發到那裏。在實踐中,這有時行不通。因此,您可能需要考慮
 通過自己安裝最新的Linux內核內核來繞過供應商。如果如果您選擇此方法,那麼本指
 南後面的步驟將解釋如何在排除了其他可能導致您的問題的原因後執行此操作。
 
-注意前段使用的詞語是「大多數」,因爲有時候開發人員實際上願意處理供應商內核出現
+注意前段使用的詞語是“大多數”,因爲有時候開發人員實際上願意處理供應商內核出現
 的問題報告。他們是否這麼做很大程度上取決於開發人員和相關問題。如果發行版只
 根據最近的Linux版本對內核進行了較小修改,那麼機會就比較大;例如對於Debian
 GNU/Linux Sid或Fedora Rawhide所提供的主線內核。一些開發人員還將接受基於最新
 穩定內核的發行版內核問題報告,只要它改動不大;例如Arch Linux、常規Fedora版本
 和openSUSE Turboweed。但是請記住,您最好使用主線Linux,並避免在此流程中使用
-穩定版內核,如「安裝一個新的內核進行測試」一節中所詳述。
+穩定版內核,如“安裝一個新的內核進行測試”一節中所詳述。
 
-當然,您可以忽略所有這些建議,並向上游Linux開發人員報告舊的或經過大量修改的
+當然,您可以忽略所有這些建議,並向上遊Linux開發人員報告舊的或經過大量修改的
 供應商內核的問題。但是注意,這樣的報告經常被拒絕或忽視,所以自行小心考慮一下。
 不過這還是比根本不報告問題要好:有時候這樣的報告會直接或間接地幫助解決之後的
 問題。
@@ -256,64 +253,61 @@ GNU/Linux Sid或Fedora Rawhide所提供的主線內核。一些開發人員還
 搜索現有報告(第一部分)
 -------------------------
 
-    *使用您喜愛的網絡搜尋引擎對現有報告進行粗略搜索;此外,請檢查Linux內核
+    *使用您喜愛的網絡搜索引擎對現有報告進行粗略搜索;此外,請檢查Linux內核
     郵件列表(LKML)的存檔。如果找到匹配的報告,請加入討論而不是發送新報告。*
 
 報告一個別人已經提出的問題,對每個人來說都是浪費時間,尤其是作爲報告人的你。
 所以徹底檢查是否有人已經報告了這個問題,這對你自己是有利的。在流程中的這一步,
-可以只執行一個粗略的搜索:一旦您知道您的問題需要報告到哪裡,稍後的步驟將告訴
+可以只執行一個粗略的搜索:一旦您知道您的問題需要報告到哪裏,稍後的步驟將告訴
 您如何詳細搜索。儘管如此,不要倉促完成這一步,它可以節省您的時間和減少麻煩。
 
-只需先用你最喜歡的搜尋引擎在網際網路上搜索。然後再搜索Linux內核郵件列表(LKML)
+只需先用你最喜歡的搜索引擎在互聯網上搜索。然後再搜索Linux內核郵件列表(LKML)
 存檔。
 
-如果搜索結果實在太多,可以考慮讓你的搜尋引擎將搜索時間範圍限制在過去的一個
-月或一年。而且無論你在哪裡搜索,一定要用恰當的搜索關鍵詞;也要變化幾次關鍵
-詞。同時,試著從別人的角度看問題:這將幫助你想出其他的關鍵詞。另外,一定不
+如果搜索結果實在太多,可以考慮讓你的搜索引擎將搜索時間範圍限制在過去的一個
+月或一年。而且無論你在哪裏搜索,一定要用恰當的搜索關鍵詞;也要變化幾次關鍵
+詞。同時,試着從別人的角度看問題:這將幫助你想出其他的關鍵詞。另外,一定不
 要同時使用過多的關鍵詞。記住搜索時要同時嘗試包含和不包含內核驅動程序的名稱
-或受影響的硬體組件的名稱等信息。但其確切的品牌名稱(比如說「華碩紅魔 Radeon
-RX 5700 XT Gaming OC」)往往幫助不大,因爲它太具體了。相反,嘗試搜索術語,如
-型號(Radeon 5700 或 Radeon 5000)和核心代號(「Navi」或「Navi10」),以及包含
-和不包含其製造商(「AMD」)。
+或受影響的硬件組件的名稱等信息。但其確切的品牌名稱(比如說“華碩紅魔 Radeon
+RX 5700 XT Gaming OC”)往往幫助不大,因爲它太具體了。相反,嘗試搜索術語,如
+型號(Radeon 5700 或 Radeon 5000)和核心代號(“Navi”或“Navi10”),以及包含
+和不包含其製造商(“AMD”)。
 
 如果你發現了關於你的問題的現有報告,請加入討論,因爲你可能會提供有價值的額
 外信息。這一點很重要,即使是在修復程序已經準備好或處於最後階段,因爲開發人
-員可能會尋找能夠提供額外信息或測試建議修復程序的人。跳到「發布報告後的責任」
-一節,了解有關如何正確參與的細節。
+員可能會尋找能夠提供額外信息或測試建議修復程序的人。跳到“發佈報告後的責任”
+一節,瞭解有關如何正確參與的細節。
 
 注意,搜索 `bugzilla.kernel.org <https://bugzilla.kernel.org/>`_ 網站可能
 也是一個好主意,因爲這可能會提供有價值的見解或找到匹配的報告。如果您發現後者,
-請記住:大多數子系統都希望在不同的位置報告,如下面「你需要將問題報告到何處」
+請記住:大多數子系統都希望在不同的位置報告,如下面“你需要將問題報告到何處”
 一節中所述。因此本應處理這個問題的開發人員甚至可能不知道bugzilla的工單。所以
 請檢查工單中的問題是否已經按照本文檔所述得到報告,如果沒有,請考慮這樣做。
 
 高優先級的問題?
 -----------------
 
-    *看看你正在處理的問題是否是回歸問題、安全問題或非常嚴重的問題:這些都是
-    需要在接下來的一些步驟中特別處理的「高優先級問題」。*
+    *看看你正在處理的問題是否是迴歸問題、安全問題或非常嚴重的問題:這些都是
+    需要在接下來的一些步驟中特別處理的“高優先級問題”。*
 
 Linus Torvalds和主要的Linux內核開發人員希望看到一些問題儘快得到解決,因此在
-報告過程中有一些「高優先級問題」的處理略有不同。有三種情況符合條件:回歸、安全
+報告過程中有一些“高優先級問題”的處理略有不同。有三種情況符合條件:迴歸、安全
 問題和非常嚴重的問題。
 
-如果在舊版本的Linux內核中工作的東西不能在新版本的Linux內核中工作,或者某種
-程度上在新版本的Linux內核中工作得更差,那麼你就需要處理「回歸」。因此,當一個
-在Linux 5.7中表現良好的WiFi驅動程序在5.8中表現不佳或根本不能工作時,這是一
-種回歸。如果應用程式在新的內核中出現不穩定的現象,這也是一種回歸,這可能是
-由於內核和用戶空間之間的接口(如procfs和sysfs)發生不兼容的更改造成的。顯著
-的性能降低或功耗增加也可以稱爲回歸。但是請記住:新內核需要使用與舊內核相似的
-配置來構建(參見下面如何實現這一點)。這是因爲內核開發人員在實現新特性時有
-時無法避免不兼容性;但是爲了避免回歸,這些特性必須在構建配置期間顯式地啓用。
+如果某個應用程序或實際用例在原先的Linux內核上運行良好,但在使用類似配置編譯的
+較新版本上效果更差、或者根本不能用,那麼你就需要處理迴歸問題。
+Documentation/admin-guide/reporting-regressions.rst 對此進行了更詳細的解釋。
+它還提供了很多你可能想知道的關於迴歸的其他信息;例如,它解釋瞭如何將您的問題
+添加到迴歸跟蹤列表中,以確保它不會被忽略。
 
 什麼是安全問題留給您自己判斷。在繼續之前,請考慮閱讀
-「Documentation/translations/zh_TW/admin-guide/security-bugs.rst」,
-因爲它提供了如何最恰當地處理安全問題的額外細節。
+Documentation/translations/zh_CN/admin-guide/security-bugs.rst ,
+因爲它提供瞭如何最恰當地處理安全問題的額外細節。
 
-當發生了完全無法接受的糟糕事情時,此問題就是一個「非常嚴重的問題」。例如,
-Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核突然顯示錯誤消息
-(「kernel panic」)並停止工作,或者根本沒有任何停止信息時,您也在處理一個嚴重
-的問題。注意:不要混淆「panic」(內核停止自身的致命錯誤)和「Oops」(可恢復錯誤),
+當發生了完全無法接受的糟糕事情時,此問題就是一個“非常嚴重的問題”。例如,
+Linux內核破壞了它處理的數據或損壞了它運行的硬件。當內核突然顯示錯誤消息
+(“kernel panic”)並停止工作,或者根本沒有任何停止信息時,您也在處理一個嚴重
+的問題。注意:不要混淆“panic”(內核停止自身的致命錯誤)和“Oops”(可恢復錯誤),
 因爲顯示後者之後內核仍然在運行。
 
 
@@ -325,22 +319,22 @@ Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核
 看起來很像內核問題的問題有時是由構建或運行時環境引起的。很難完全排除這種問
 題,但你應該儘量減少這種問題:
 
- * 構建內核時,請使用經過驗證的工具,因爲編譯器或二進位文件中的錯誤可能會導
+ * 構建內核時,請使用經過驗證的工具,因爲編譯器或二進制文件中的錯誤可能會導
    致內核出現錯誤行爲。
 
  * 確保您的計算機組件在其設計規範內運行;這對處理器、內存和主板尤爲重要。因
    此,當面臨潛在的內核問題時,停止低電壓或超頻。
 
- * 儘量確保不是硬體故障導致了你的問題。例如,內存損壞會導致大量的問題,這些
+ * 儘量確保不是硬件故障導致了你的問題。例如,內存損壞會導致大量的問題,這些
    問題會表現爲看起來像內核問題。
 
  * 如果你正在處理一個文件系統問題,你可能需要用 ``fsck`` 檢查一下文件系統,
    因爲它可能會以某種方式被損壞,從而導致無法預期的內核行爲。
 
- * 在處理回歸問題時,要確保沒有在更新內核的同時發生了其他變化。例如,這個問
-   題可能是由同時更新的其他軟體引起的。也有可能是在你第一次重啓進入新內核時,
-   某個硬體巧合地壞了。更新系統 BIOS 或改變 BIOS 設置中的某些內容也會導致
-   一些看起來很像內核回歸的問題。
+ * 在處理迴歸問題時,要確保沒有在更新內核的同時發生了其他變化。例如,這個問
+   題可能是由同時更新的其他軟件引起的。也有可能是在你第一次重啓進入新內核時,
+   某個硬件巧合地壞了。更新系統 BIOS 或改變 BIOS 設置中的某些內容也會導致
+   一些看起來很像內核迴歸的問題。
 
 
 爲緊急情況做好準備
@@ -349,8 +343,8 @@ Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核
     *創建一個全新的備份,並將系統修復和還原工具放在手邊*
 
 我得提醒您,您正在和計算機打交道,計算機有時會出現意想不到的事情,尤其是當
-您折騰其作業系統的內核等關鍵部件時。而這就是你在這個過程中要做的事情。因此,
-一定要創建一個全新的備份;還要確保你手頭有修復或重裝作業系統的所有工具,
+您折騰其操作系統的內核等關鍵部件時。而這就是你在這個過程中要做的事情。因此,
+一定要創建一個全新的備份;還要確保你手頭有修復或重裝操作系統的所有工具,
 以及恢復備份所需的一切。
 
 
@@ -366,67 +360,67 @@ Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核
 的任何模塊。然後重新啓動再繼續。
 
 注意,你可能不知道你的系統正在使用這些解決方案之一:當你安裝 Nvidia 專有圖
-形驅動程序、VirtualBox 或其他需要 Linux 內核以外的模塊支持的軟體時,它們通
-常會靜默設置。這就是爲什麼你可能需要卸載這些軟體的軟體包,以擺脫任何第三方
+形驅動程序、VirtualBox 或其他需要 Linux 內核以外的模塊支持的軟件時,它們通
+常會靜默設置。這就是爲什麼你可能需要卸載這些軟件的軟件包,以擺脫任何第三方
 內核模塊。
 
 
-檢測「汙染」標誌
+檢查“污染”標誌
 ----------------
 
-    *當問題發生時,檢查您的內核是否被「汙染」,因爲使內核設置這個標誌的事件可
+    *當問題發生時,檢查您的內核是否被“污染”,因爲使內核設置這個標誌的事件可
     能會導致您面臨的問題。*
 
-當某些可能會導致看起來完全不相關的後續錯誤的事情發生時,內核會用「汙染
-(taint)」標誌標記自己。如果您的內核受到汙染,那麼您面臨的可能是這樣的錯誤。
+當某些可能會導致看起來完全不相關的後續錯誤的事情發生時,內核會用“污染
+(taint)”標誌標記自己。如果您的內核受到污染,那麼您面臨的可能是這樣的錯誤。
 因此在投入更多時間到這個過程中之前,儘早排除此情況可能對你有好處。這是這個
-步驟出現在這裡的唯一原因,因爲這個過程稍後會告訴您安裝最新的主線內核;然後
-您將需要再次檢查汙染標誌,因爲當它出問題的時候內核報告會關注它。
+步驟出現在這裏的唯一原因,因爲這個過程稍後會告訴您安裝最新的主線內核;然後
+您將需要再次檢查污染標誌,因爲當它出問題的時候內核報告會關注它。
 
-在正在運行的系統上檢查內核是否汙染非常容易:如果 ``cat /proc/sys/kernel/tainted``
-返回「0」,那麼內核沒有被汙染,一切正常。在某些情況下無法檢查該文件;這就是
-爲什麼當內核報告內部問題(「kernel bug」)、可恢復錯誤(「kernel Oops」)或停止
-操作前不可恢復的錯誤(「kernel panic」)時,它也會提到汙染狀態。當其中一個錯
-誤發生時,查看列印的錯誤消息的頂部,搜索以「CPU:」開頭的行。如果發現問題時內
-核未被汙染,那麼它應該以「Not infected」結束;如果你看到「Tainted:」且後跟一些
-空格和字母,那就被汙染了。
+在正在運行的系統上檢查內核是否污染非常容易:如果 ``cat /proc/sys/kernel/tainted``
+返回“0”,那麼內核沒有被污染,一切正常。在某些情況下無法檢查該文件;這就是
+爲什麼當內核報告內部問題(“kernel bug”)、可恢復錯誤(“kernel Oops”)或停止
+操作前不可恢復的錯誤(“kernel panic”)時,它也會提到污染狀態。當其中一個錯
+誤發生時,查看打印的錯誤消息的頂部,搜索以“CPU:”開頭的行。如果發現問題時內
+核未被污染,那麼它應該以“Not infected”結束;如果你看到“Tainted:”且後跟一些
+空格和字母,那就被污染了。
 
-如果你的內核被汙染了,請閱讀「Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst」
-以找出原因。設法消除汙染因素。通常是由以下三種因素之一引起的:
+如果你的內核被污染了,請閱讀 Documentation/translations/zh_CN/admin-guide/tainted-kernels.rst
+以找出原因。設法消除污染因素。通常是由以下三種因素之一引起的:
 
- 1. 發生了一個可恢復的錯誤(「kernel Oops」),內核汙染了自己,因爲內核知道在
+ 1. 發生了一個可恢復的錯誤(“kernel Oops”),內核污染了自己,因爲內核知道在
     此之後它可能會出現奇怪的行爲錯亂。在這種情況下,檢查您的內核或系統日誌,
     並尋找以下列文字開頭的部分::
 
        Oops: 0000 [#1] SMP
 
-    如方括號中的「#1」所示,這是自啓動以來的第一次Oops。每個Oops和此後發生的
+    如方括號中的“#1”所示,這是自啓動以來的第一次Oops。每個Oops和此後發生的
     任何其他問題都可能是首個Oops的後續問題,即使這兩個問題看起來完全不相關。
     通過消除首個Oops的原因並在之後復現該問題,可以排除這種情況。有時僅僅
     重新啓動就足夠了,有時更改配置後重新啓動可以消除Oops。但是在這個流程中
     不要花費太多時間在這一點上,因爲引起Oops的原因可能已經在您稍後將按流程
     安裝的新Linux內核版本中修復了。
 
- 2. 您的系統使用的軟體安裝了自己的內核模塊,例如Nvidia的專有圖形驅動程序或
-    VirtualBox。當內核從外部源(即使它們是開源的)加載此類模塊時,它會汙染
+ 2. 您的系統使用的軟件安裝了自己的內核模塊,例如Nvidia的專有圖形驅動程序或
+    VirtualBox。當內核從外部源(即使它們是開源的)加載此類模塊時,它會污染
     自己:它們有時會在不相關的內核區域導致錯誤,從而可能導致您面臨的問題。
     因此,當您想要向Linux內核開發人員報告問題時,您必須阻止這些模塊加載。
-    大多數情況下最簡單的方法是:臨時卸載這些軟體,包括它們可能已經安裝的任
+    大多數情況下最簡單的方法是:臨時卸載這些軟件,包括它們可能已經安裝的任
     何模塊。之後重新啓動。
 
- 3. 當內核加載駐留在Linux內核原始碼staging樹中的模塊時,它也會汙染自身。這
+ 3. 當內核加載駐留在Linux內核源代碼staging樹中的模塊時,它也會污染自身。這
     是一個特殊的區域,代碼(主要是驅動程序)還沒有達到正常Linux內核的質量
-    標準。當您報告此種模塊的問題時,內核受到汙染顯然是沒有問題的;只需確保
-    問題模塊是造成汙染的唯一原因。如果問題發生在一個不相關的區域,重新啓動
+    標準。當您報告此種模塊的問題時,內核受到污染顯然是沒有問題的;只需確保
+    問題模塊是造成污染的唯一原因。如果問題發生在一個不相關的區域,重新啓動
     並通過指定 ``foo.blacklist=1`` 作爲內核參數臨時阻止該模塊被加載(用有
-    問題的模塊名替換「foo」)。
+    問題的模塊名替換“foo”)。
 
 
 記錄如何重現問題
 ------------------
 
     *粗略地寫下如何重現這個問題。如果您同時處理多個問題,請爲每個問題單獨寫
-    注釋,並確保它們在新啓動的系統上獨立出現。這是必要的,因爲每個問題都需
+    註釋,並確保它們在新啓動的系統上獨立出現。這是必要的,因爲每個問題都需
     要分別報告給內核開發人員,除非它們嚴重糾纏在一起。*
 
 如果你同時處理多個問題,必須分別報告每個問題,因爲它們可能由不同的開發人員
@@ -438,20 +432,20 @@ Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核
 
 注意:報告只發生過一次的問題往往是沒有結果的,因爲它們可能是由於宇宙輻射導
 致的位翻轉。所以你應該嘗試通過重現問題來排除這種情況,然後再繼續。如果你有
-足夠的經驗來區分由於硬體故障引起的一次性錯誤和難以重現的罕見內核問題,可以
+足夠的經驗來區分由於硬件故障引起的一次性錯誤和難以重現的罕見內核問題,可以
 忽略這個建議。
 
 
-穩定版或長期支持內核的回歸?
+穩定版或長期支持內核的迴歸?
 -----------------------------
 
-    *如果您正面臨穩定版或長期支持版本線的回歸(例如從5.10.4更新到5.10.5時出現
-    故障),請查看後文「報告穩定版和長期支持內核線的回歸」小節。*
+    *如果您正面臨穩定版或長期支持版本線的迴歸(例如從5.10.4更新到5.10.5時出現
+    故障),請查看後文“報告穩定版和長期支持內核線的迴歸”小節。*
 
-穩定版和長期支持內核版本線中的回歸是Linux開發人員非常希望解決的問題,這樣的
-問題甚至比主線開發分支中的回歸更不應出現,因爲它們會很快影響到很多人。開發人員
-希望儘快了解此類問題,因此有一個簡化流程來報告這些問題。注意,使用更新內核版
-本線的回歸(比如從5.9.15切換到5.10.5時出現故障)不符合條件。
+穩定版和長期支持內核版本線中的迴歸是Linux開發人員非常希望解決的問題,這樣的
+問題甚至比主線開發分支中的迴歸更不應出現,因爲它們會很快影響到很多人。開發人員
+希望儘快瞭解此類問題,因此有一個簡化流程來報告這些問題。注意,使用更新內核版
+本線的迴歸(比如從5.9.15切換到5.10.5時出現故障)不符合條件。
 
 
 你需要將問題報告到何處
@@ -462,9 +456,9 @@ Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核
     過郵件發送給維護人員和公共郵件列表。*
 
 將報告發送給合適的人是至關重要的,因爲Linux內核是一個大項目,大多數開發人員
-只熟悉其中的一小部分。例如,相當多的程式設計師只關心一個驅動程序,比如一個WiFi
-晶片驅動程序;它的開發人員可能對疏遠的或不相關的「子系統」(如TCP堆棧、
-PCIe/PCI子系統、內存管理或文件系統)的內部知識了解很少或完全不了解。
+只熟悉其中的一小部分。例如,相當多的程序員只關心一個驅動程序,比如一個WiFi
+芯片驅動程序;它的開發人員可能對疏遠的或不相關的“子系統”(如TCP堆棧、
+PCIe/PCI子系統、內存管理或文件系統)的內部知識瞭解很少或完全不瞭解。
 
 問題在於:Linux內核缺少一個,可以簡單地將問題歸檔並讓需要了解它的開發人員了
 解它的,中心化缺陷跟蹤器。這就是爲什麼你必須找到正確的途徑來自己報告問題。
@@ -476,10 +470,10 @@ PCIe/PCI子系統、內存管理或文件系統)的內部知識了解很少或
 
 爲了說明如何使用 :ref:`MAINTAINERS <maintainers>` 文件,讓我們假設您的筆記
 本電腦中的WiFi在更新內核後突然出現了錯誤行爲。這種情況下可能是WiFi驅動的問
-題。顯然,它也可能由於驅動基於的某些代碼,但除非你懷疑有這樣的東西會附著在
-驅動程序上。如果真的是其他的問題,驅動程序的開發人員會讓合適的人參與進來。
+題。顯然,它也可能由於驅動基於的某些代碼,但除非你懷疑有這樣的東西會附着在
+驅動程序上。如果真的是其他的問題,驅動程序的開發人員會讓合適的人蔘與進來。
 
-遺憾的是,沒有通用且簡單的辦法來檢查哪個代碼驅動了特定硬體組件。
+遺憾的是,沒有通用且簡單的辦法來檢查哪個代碼驅動了特定硬件組件。
 
 在WiFi驅動出現問題的情況下,你可能想查看 ``lspci -k`` 的輸出,因爲它列出了
 PCI/PCIe總線上的設備和驅動它的內核模塊::
@@ -492,19 +486,19 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
          Kernel modules: ath10k_pci
        [...]
 
-但如果你的WiFi晶片通過USB或其他內部總線連接,這種方法就行不通了。在這種情況
+但如果你的WiFi芯片通過USB或其他內部總線連接,這種方法就行不通了。在這種情況
 下,您可能需要檢查您的WiFi管理器或 ``ip link`` 的輸出。尋找有問題的網絡接口
-的名稱,它可能類似於「wlp58s0」。此名稱可以用來找到驅動它的模塊::
+的名稱,它可能類似於“wlp58s0”。此名稱可以用來找到驅動它的模塊::
 
        [user@something ~]$ realpath --relative-to=/sys/module//sys/class/net/wlp58s0/device/driver/module
        ath10k_pci
 
 如果這些技巧不能進一步幫助您,請嘗試在網上搜索如何縮小相關驅動程序或子系統
-的範圍。如果你不確定是哪一個:試著猜一下,即使你猜得不好,也會有人會幫助你
+的範圍。如果你不確定是哪一個:試着猜一下,即使你猜得不好,也會有人會幫助你
 的。
 
 一旦您知道了相應的驅動程序或子系統,您就希望在MAINTAINERS文件中搜索它。如果
-是「ath10k_pci」,您不會找到任何東西,因爲名稱太具體了。有時你需要在網上尋找
+是“ath10k_pci”,您不會找到任何東西,因爲名稱太具體了。有時你需要在網上尋找
 幫助;但在此之前,請嘗試使用一個稍短或修改過的名稱來搜索MAINTAINERS文件,因
 爲這樣你可能會發現類似這樣的東西::
 
@@ -516,23 +510,23 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
        SCM:           git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
        Files:         drivers/net/wireless/ath/ath10k/
 
-注意:如果您閱讀在Linux原始碼樹的根目錄中找到的原始維護者文件,則行描述將是
-縮寫。例如,「Mail:(郵件)」將是「M:」,「Mailing list:(郵件列表)」將是「L」,
-「Status:(狀態)」將是「S:」。此文件頂部有一段解釋了這些和其他縮寫。
+注意:如果您閱讀在Linux源代碼樹的根目錄中找到的原始維護者文件,則行描述將是
+縮寫。例如,“Mail:(郵件)”將是“M:”,“Mailing list:(郵件列表)”將是“L”,
+“Status:(狀態)”將是“S:”。此文件頂部有一段解釋了這些和其他縮寫。
 
-首先查看「Status」狀態行。理想情況下,它應該得到「Supported(支持)」或
-「Maintained(維護)」。如果狀態爲「Obsolete(過時的)」,那麼你在使用一些過時的
-方法,需要轉換到新的解決方案上。有時候,只有在感到有動力時,才會有人爲代碼
-提供「Odd Fixes」。如果碰見「Orphan」,你就完全不走運了,因爲再也沒有人關心代碼
-了,只剩下這些選項:準備好與問題共存,自己修復它,或者找一個願意修復它的程式設計師。
+首先查看“Status”狀態行。理想情況下,它應該得到“Supported(支持)”或
+“Maintained(維護)”。如果狀態爲“Obsolete(過時的)”,那麼你在使用一些過時的
+方法,需要轉換到新的解決方案上。有時候,只有在感到有動力時,纔會有人爲代碼
+提供“Odd Fixes”。如果碰見“Orphan”,你就完全不走運了,因爲再也沒有人關心代碼
+了,只剩下這些選項:準備好與問題共存,自己修復它,或者找一個願意修復它的程序員。
 
-檢查狀態後,尋找以「bug:」開頭的一行:它將告訴你在哪裡可以找到子系統特定的缺
+檢查狀態後,尋找以“bug:”開頭的一行:它將告訴你在哪裏可以找到子系統特定的缺
 陷跟蹤器來提交你的問題。上面的例子沒有此行。大多數部分都是這樣,因爲 Linux
 內核的開發完全是由郵件驅動的。很少有子系統使用缺陷跟蹤器,且其中只有一部分
 依賴於 bugzilla.kernel.org。
 
-在這種以及其他很多情況下,你必須尋找以「Mail:」開頭的行。這些行提到了特定代碼
-的維護者的名字和電子郵件地址。也可以查找以「Mailing list:」開頭的行,它告訴你
+在這種以及其他很多情況下,你必須尋找以“Mail:”開頭的行。這些行提到了特定代碼
+的維護者的名字和電子郵件地址。也可以查找以“Mailing list:”開頭的行,它告訴你
 開發代碼的公共郵件列表。你的報告之後需要通過郵件發到這些地址。另外,對於所有
 通過電子郵件發送的問題報告,一定要抄送 Linux Kernel Mailing List(LKML)
 <linux-kernel@vger.kernel.org>。在以後通過郵件發送問題報告時,不要遺漏任何
@@ -544,8 +538,8 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
 ~~~~~~~~~~~~~~~~~~~~
 
 對於手頭有Linux源碼的人來說,有第二個可以找到合適的報告地點的選擇:腳本
-「scripts/get_maintainer.pl」,它嘗試找到所有要聯繫的人。它會查詢MAINTAINERS
-文件,並需要用相關原始碼的路徑來調用。對於編譯成模塊的驅動程序,經常可以用
+“scripts/get_maintainer.pl”,它嘗試找到所有要聯繫的人。它會查詢MAINTAINERS
+文件,並需要用相關源代碼的路徑來調用。對於編譯成模塊的驅動程序,經常可以用
 這樣的命令找到::
 
        $ modinfo ath10k_pci | grep filename | sed 's!/lib/modules/.*/kernel/!!; s!filename:!!; s!\.ko\(\|\.xz\)!!'
@@ -561,13 +555,13 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
        netdev@vger.kernel.org (open list:NETWORKING DRIVERS)
        linux-kernel@vger.kernel.org (open list)
 
-不要把你的報告發給所有的人。發送給維護者,腳本稱之爲「supporter:」;另外抄送
+不要把你的報告發給所有的人。發送給維護者,腳本稱之爲“supporter:”;另外抄送
 代碼最相關的郵件列表,以及 Linux 內核郵件列表(LKML)。在此例中,你需要將報
-告發送給 「Some Human <shuman@example.com>」 ,並抄送
-「ath10k@lists.infradead.org」和「linux-kernel@vger.kernel.org」。
+告發送給 “Some Human <shuman@example.com>” ,並抄送
+“ath10k@lists.infradead.org”和“linux-kernel@vger.kernel.org”。
 
-注意:如果你用 git 克隆了 Linux 原始碼,你可能需要用--git 再次調用
-get_maintainer.pl。腳本會查看提交歷史,以找到最近哪些人參與了相關代碼的編寫,
+注意:如果你用 git 克隆了 Linux 源代碼,你可能需要用--git 再次調用
+get_maintainer.pl。腳本會查看提交歷史,以找到最近哪些人蔘與了相關代碼的編寫,
 因爲他們可能會提供幫助。但要小心使用這些結果,因爲它很容易讓你誤入歧途。
 例如,這種情況常常會發生在很少被修改的地方(比如老舊的或未維護的驅動程序):
 有時這樣的代碼會在樹級清理期間被根本不關心此驅動程序的開發者修改。
@@ -580,73 +574,74 @@ get_maintainer.pl。腳本會查看提交歷史,以找到最近哪些人參與
     如果找到匹配的報告,請加入討論而不是發送新報告。*
 
 如前所述:報告一個別人已經提出的問題,對每個人來說都是浪費時間,尤其是作爲報告
-人的你。這就是爲什麼你應該再次搜索現有的報告。現在你已經知道問題需要報告到哪裡。
+人的你。這就是爲什麼你應該再次搜索現有的報告。現在你已經知道問題需要報告到哪裏。
 如果是郵件列表,那麼一般在 `lore.kernel.org <https://lore.kernel.org/>`_ 可以
 找到相應存檔。
 
 但有些列表運行在其他地方。例如前面步驟中當例子的ath10k WiFi驅動程序就是這種
-情況。但是你通常可以在網上很容易地找到這些列表的檔案。例如搜索「archive
-ath10k@lists.infradead.org」,將引導您到ath10k郵件列表的信息頁,該頁面頂部連結
+情況。但是你通常可以在網上很容易地找到這些列表的檔案。例如搜索“archive
+ath10k@lists.infradead.org”,將引導您到ath10k郵件列表的信息頁,該頁面頂部鏈接
 到其 `列表存檔 <https://lists.infradead.org/pipermail/ath10k/>`_ 。遺憾的是,
-這個列表和其他一些列表缺乏搜索其存檔的功能。在這種情況下可以使用常規的網際網路
-搜尋引擎,並添加類似「site:lists.infadead.org/pipermail/ath10k/」這
-樣的搜索條件,這會把結果限制在該連結中的檔案。
+這個列表和其他一些列表缺乏搜索其存檔的功能。在這種情況下可以使用常規的互聯網
+搜索引擎,並添加類似“site:lists.infadead.org/pipermail/ath10k/”這
+樣的搜索條件,這會把結果限制在該鏈接中的檔案。
 
-也請進一步搜索網絡、LKML和bugzilla.kernel.org網站。
+也請進一步搜索網絡、LKML和bugzilla.kernel.org網站。如果你的報告需要發送到缺陷
+跟蹤器中,那麼您可能還需要檢查子系統的郵件列表存檔,因爲可能有人只在那裏報告了它。
 
-有關如何搜索以及在找到匹配報告時如何操作的詳細信息,請參閱上面的「搜索現有報告
-(第一部分)」。
+有關如何搜索以及在找到匹配報告時如何操作的詳細信息,請參閱上面的“搜索現有報告
+(第一部分)”。
 
-不要急著完成報告過程的這一步:花30到60分鐘甚至更多的時間可以爲你和其他人節省 /
+不要急着完成報告過程的這一步:花30到60分鐘甚至更多的時間可以爲你和其他人節省 /
 減少相當多的時間和麻煩。
 
 
 安裝一個新的內核進行測試
 --------------------------
 
-    *除非您已經在運行最新的「主線」Linux內核,否則最好在報告流程前安裝它。在
-    某些情況下,使用最新的「穩定版」Linux進行測試和報告也是可以接受的替代方案;
+    *除非您已經在運行最新的“主線”Linux內核,否則最好在報告流程前安裝它。在
+    某些情況下,使用最新的“穩定版”Linux進行測試和報告也是可以接受的替代方案;
     在合併窗口期間,這實際上可能是最好的方法,但在開發階段最好還是暫停幾天。
-    無論你選擇什麼版本,最好使用「普通」構建。忽略這些建議會大大增加您的報告
+    無論你選擇什麼版本,最好使用“普通”構建。忽略這些建議會大大增加您的報告
     被拒絕或忽略的風險。*
 
-正如第一步的詳細解釋中所提到的:與大多數程式設計師一樣,與大多數程式設計師一樣,Linux
-內核開發人員不喜歡花時間處理他們維護的原始碼中根本不會發生的問題的報告。這隻
+正如第一步的詳細解釋中所提到的:與大多數程序員一樣,與大多數程序員一樣,Linux
+內核開發人員不喜歡花時間處理他們維護的源代碼中根本不會發生的問題的報告。這隻
 會浪費每個人的時間,尤其是你的時間。這就是爲什麼在報告問題之前,您必須先確認
 問題仍然存在於最新的上游代碼中,這符合每個人的利益。您可以忽略此建議,但如前
 所述:這樣做會極大地增加問題報告被拒絕或被忽略的風險。
 
-內核「最新上游」的範圍通常指:
+內核“最新上游”的範圍通常指:
 
  * 安裝一個主線內核;最新的穩定版內核也可以是一個選擇,但大多數時候都最好避免。
-   長期支持內核(有時稱爲「LTS內核」)不適合此流程。下一小節將更詳細地解釋所有
+   長期支持內核(有時稱爲“LTS內核”)不適合此流程。下一小節將更詳細地解釋所有
    這些。
 
  * 下一小節描述獲取和安裝這樣一個內核的方法。它還指出了使用預編譯內核是可以的,
-   但普通的內核更好,這意味著:它是直接使用從 `kernel.org <https://kernel.org/>`_
-   獲得的Linux原始碼構建並且沒有任何方式修改或增強。
+   但普通的內核更好,這意味着:它是直接使用從 `kernel.org <https://kernel.org/>`_
+   獲得的Linux源代碼構建並且沒有任何方式修改或增強。
 
 
 選擇適合測試的版本
 ~~~~~~~~~~~~~~~~~~~~
 
-前往 `kernel.org <https://kernel.org/>`_ 來決定使用哪個版本。忽略那個寫著
-「Latest release最新版本」的巨大黃色按鈕,往下看有一個表格。在表格的頂部,你會
-看到一行以「mainline」開頭的字樣,大多數情況下它會指向一個版本號類似「5.8-rc2」
-的預發布版本。如果是這樣的話,你將需要使用這個主線內核進行測試。不要讓「rc」
-嚇到你,這些「開發版內核」實際上非常可靠——而且你已經按照上面的指示做了備份,
+前往 `kernel.org <https://kernel.org/>`_ 來決定使用哪個版本。忽略那個寫着
+“Latest release最新版本”的巨大黃色按鈕,往下看有一個表格。在表格的頂部,你會
+看到一行以“mainline”開頭的字樣,大多數情況下它會指向一個版本號類似“5.8-rc2”
+的預發佈版本。如果是這樣的話,你將需要使用這個主線內核進行測試。不要讓“rc”
+嚇到你,這些“開發版內核”實際上非常可靠——而且你已經按照上面的指示做了備份,
 不是嗎?
 
-大概每九到十周,「mainline」可能會給你指出一個版本號類似「5.7」的正式版本。如果
-碰見這種情況,請考慮暫停報告過程,直到下一個版本的第一個預發布(5.8-rc1)出
-現在 `kernel.org <https://kernel.org/>`_ 上。這是因爲 Linux 的開發周期正在
-兩周的「合併窗口」內。大部分的改動和所有干擾性的改動都會在這段時間內被合併到
+大概每九到十週,“mainline”可能會給你指出一個版本號類似“5.7”的正式版本。如果
+碰見這種情況,請考慮暫停報告過程,直到下一個版本的第一個預發佈(5.8-rc1)出
+現在 `kernel.org <https://kernel.org/>`_ 上。這是因爲 Linux 的開發週期正在
+兩週的“合併窗口”內。大部分的改動和所有干擾性的改動都會在這段時間內被合併到
 下一個版本中。在此期間使用主線是比較危險的。內核開發者通常也很忙,可能沒有
 多餘的時間來處理問題報告。這也是很有可能在合併窗口中應用了許多修改來修復你
-所面臨的問題;這就是爲什麼你很快就得用一個新的內核版本重新測試,就像下面「發
-布報告後的責任」一節中所述的那樣。
+所面臨的問題;這就是爲什麼你很快就得用一個新的內核版本重新測試,就像下面“發
+布報告後的責任”一節中所述的那樣。
 
-這就是爲什麼要等到合併窗口結束後才去做。但是如果你處理的是一些不應該等待的
+這就是爲什麼要等到合併窗口結束後纔去做。但是如果你處理的是一些不應該等待的
 東西,則無需這樣做。在這種情況下,可以考慮通過 git 獲取最新的主線內核(見下
 文),或者使用 kernel.org 上提供的最新穩定版本。如果 mainline 因爲某些原因
 不無法正常工作,那麼使用它也是可以接受的。總的來說:用它來重現問題也比完全
@@ -657,7 +652,7 @@ ath10k@lists.infradead.org」,將引導您到ath10k郵件列表的信息頁,
 需要先在主線修復,然後才能得到回傳,這可能需要幾天或幾周。另一個原因是:您
 希望的修復對於回傳來說可能太難或太冒險;因此再次報告問題不太可能改變任何事情。
 
-這些方面也部分表明了爲什麼長期支持內核(有時稱爲「LTS內核」)不適合報告流程:
+這些方面也部分表明了爲什麼長期支持內核(有時稱爲“LTS內核”)不適合報告流程:
 它們與當前代碼的距離太遠。因此,先去測試主線,然後再按流程走:如果主線沒有
 出現問題,流程將指導您如何在舊版本線中修復它。
 
@@ -669,31 +664,31 @@ ath10k@lists.infradead.org」,將引導您到ath10k郵件列表的信息頁,
 
 **使用預編譯的內核** :這往往是最快速、最簡單、最安全的方法——尤其是在你不熟
 悉 Linux 內核的情況下。問題是:發行商或附加存儲庫提供的大多數版本都是從修改
-過的Linux原始碼構建的。因此它們不是普通的,通常不適合於測試和問題報告:這些
+過的Linux源代碼構建的。因此它們不是普通的,通常不適合於測試和問題報告:這些
 更改可能會導致您面臨的問題或以某種方式影響問題。
 
 但是如果您使用的是流行的Linux發行版,那麼您就很幸運了:對於大部分的發行版,
 您可以在網上找到包含最新主線或穩定版本Linux內核包的存儲庫。使用這些是完全可
-以的,只要從存儲庫的描述中確認它們是普通的或者至少接近普通。此外,請確保軟體
-包包含kernel.org上提供的最新版本內核。如果這些軟體包的時間超過一周,那麼它們
-可能就不合適了,因爲新的主線和穩定版內核通常至少每周發布一次。
+以的,只要從存儲庫的描述中確認它們是普通的或者至少接近普通。此外,請確保軟件
+包包含kernel.org上提供的最新版本內核。如果這些軟件包的時間超過一週,那麼它們
+可能就不合適了,因爲新的主線和穩定版內核通常至少每週發佈一次。
 
 請注意,您以後可能需要手動構建自己的內核:有時這是調試或測試修復程序所必需的,
 如後文所述。還要注意,預編譯的內核可能缺少在出現panic、Oops、warning或BUG時
-解碼內核列印的消息所需的調試符號;如果您計劃解碼這些消息,最好自己編譯內核
-(有關詳細信息,請參閱本小節結尾和「解碼失敗信息」小節)。
+解碼內核打印的消息所需的調試符號;如果您計劃解碼這些消息,最好自己編譯內核
+(有關詳細信息,請參閱本小節結尾和“解碼失敗信息”小節)。
 
 **使用git** :熟悉 git 的開發者和有經驗的 Linux 用戶通常最好直接從
 `kernel.org 上的官方開發倉庫
 <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/>`_
-中獲取最新的 Linux 內核原始碼。這些很可能比最新的主線預發布版本更新一些。不
-用擔心:它們和正式的預發布版本一樣可靠,除非內核的開發周期目前正處於合併窗
+中獲取最新的 Linux 內核源代碼。這些很可能比最新的主線預發佈版本更新一些。不
+用擔心:它們和正式的預發佈版本一樣可靠,除非內核的開發週期目前正處於合併窗
 口中。不過即便如此,它們也是相當可靠的。
 
 **常規方法** :不熟悉 git 的人通常最好從 `kernel.org <https://kernel.org/>`_
 下載源碼的tar 存檔包。
 
-如何實際構建一個內核並不在這裡描述,因爲許多網站已經解釋了必要的步驟。如果
+如何實際構建一個內核並不在這裏描述,因爲許多網站已經解釋了必要的步驟。如果
 你是新手,可以考慮按照那些建議使用 ``make localmodconfig`` 來做,它將嘗試獲
 取你當前內核的配置,然後根據你的系統進行一些調整。這樣做並不能使編譯出來的
 內核更好,但可以更快地編譯。
@@ -702,19 +697,19 @@ ath10k@lists.infradead.org」,將引導您到ath10k郵件列表的信息頁,
 啓用 CONFIG_KALLSYMS 選項。此外,還可以啓用 CONFIG_DEBUG_KERNEL 和
 CONFIG_DEBUG_INFO;後者是相關選項,但只有啓用前者才能開啓。請注意,
 CONFIG_DEBUG_INFO 會需要更多儲存空間來構建內核。但這是值得的,因爲這些選項將
-允許您稍後精確定位觸發問題的確切代碼行。下面的「解碼失敗信息」一節對此進行了更
+允許您稍後精確定位觸發問題的確切代碼行。下面的“解碼失敗信息”一節對此進行了更
 詳細的解釋。
 
 但請記住:始終記錄遇到的問題,以防難以重現。發送未解碼的報告總比不報告要好。
 
 
-檢查「汙染」標誌
+檢查“污染”標誌
 ----------------
 
-    *確保您剛剛安裝的內核在運行時不會「汙染」自己。*
+    *確保您剛剛安裝的內核在運行時不會“污染”自己。*
 
 正如上面已經詳細介紹過的:當發生一些可能會導致一些看起來完全不相關的後續錯
-誤的事情時,內核會設置一個「汙染」標誌。這就是爲什麼你需要檢查你剛剛安裝的內
+誤的事情時,內核會設置一個“污染”標誌。這就是爲什麼你需要檢查你剛剛安裝的內
 核是否有設置此標誌。如果有的話,幾乎在任何情況下你都需要在報告問題之前先消
 除它。詳細的操作方法請看上面的章節。
 
@@ -729,43 +724,43 @@ CONFIG_DEBUG_INFO 會需要更多儲存空間來構建內核。但這是值得
 可以考慮使用此版本線,放棄報告問題。但是請記住,只要它沒有在 `kernel.org
 <https://kernel.org/>`_ 的穩定版和長期版(以及由這些版本衍生出來的廠商內核)
 中得到修復,其他用戶可能仍然會受到它的困擾。如果你喜歡使用其中的一個,或
-者只是想幫助它們的用戶,請前往下面的「報告只發生在較舊內核版本線的問題」一節。
+者只是想幫助它們的用戶,請前往下面的“報告只發生在較舊內核版本線的問題”一節。
 
 
 優化復現問題的描述
 --------------------
 
-    *優化你的筆記:試著找到並寫出最直接的復現問題的方法。確保最終結果包含所
+    *優化你的筆記:試着找到並寫出最直接的復現問題的方法。確保最終結果包含所
     有重要的細節,同時讓第一次聽說的人容易閱讀和理解。如果您在此過程中學到
     了一些東西,請考慮再次搜索關於該問題的現有報告。*
 
 過於複雜的報告會讓別人很難理解。因此請儘量找到一個可以直接描述、易於以書面
 形式理解的再現方法。包含所有重要的細節,但同時也要儘量保持簡短。
 
-在這在前面的步驟中,你很可能已經了解了一些關於你所面臨的問題的點。利用這些
+在這在前面的步驟中,你很可能已經瞭解了一些關於你所面臨的問題的點。利用這些
 知識,再次搜索可以轉而加入的現有報告。
 
 
 解碼失敗信息
 -------------
 
-    *如果失敗涉及「panic」、「Oops」、「warning」或「BUG」,請考慮解碼內核日誌以查找
+    *如果失敗涉及“panic”、“Oops”、“warning”或“BUG”,請考慮解碼內核日誌以查找
     觸發錯誤的代碼行。*
 
-當內核檢測到內部問題時,它會記錄一些有關已執行代碼的信息。這使得在原始碼中精
+當內核檢測到內部問題時,它會記錄一些有關已執行代碼的信息。這使得在源代碼中精
 確定位觸發問題的行並顯示如何調用它成爲可能。但只有在配置內核時啓用了
 CONFIG_DEBUG_INFO 和 CONFIG_KALLSYMS選項時,這種方法才起效。如果已啓用此選項,
-請考慮解碼內核日誌中的信息。這將使我們更容易理解是什麼導致了「panic」、「Oops」、
-「warning」或「BUG」,從而增加了有人提供修復的機率。
+請考慮解碼內核日誌中的信息。這將使我們更容易理解是什麼導致了“panic”、“Oops”、
+“warning”或“BUG”,從而增加了有人提供修復的幾率。
 
-解碼可以通過Linux原始碼樹中的腳本來完成。如果您運行的內核是之前自己編譯的,
+解碼可以通過Linux源代碼樹中的腳本來完成。如果您運行的內核是之前自己編譯的,
 這樣這樣調用它::
 
 	[user@something ~]$ sudo dmesg | ./linux-5.10.5/scripts/decode_stacktrace.sh ./linux-5.10.5/vmlinux
 	/usr/lib/debug/lib/modules/5.10.10-4.1.x86_64/vmlinux /usr/src/kernels/5.10.10-4.1.x86_64/
 
 如果您運行的是打包好的普通內核,則可能需要安裝帶有調試符號的相應包。然後按以下
-方式調用腳本(如果發行版未打包,則可能需要從Linux原始碼獲取)::
+方式調用腳本(如果發行版未打包,則可能需要從Linux源代碼獲取)::
 
 	[user@something ~]$ sudo dmesg | ./linux-5.10.5/scripts/decode_stacktrace.sh \
 	/usr/lib/debug/lib/modules/5.10.10-4.1.x86_64/vmlinux /usr/src/kernels/5.10.10-4.1.x86_64/
@@ -778,10 +773,10 @@ CONFIG_DEBUG_INFO 和 CONFIG_KALLSYMS選項時,這種方法才起效。如果
 
 	[   68.387301] RIP: 0010:test_module_init (/home/username/linux-5.10.5/test-module/test-module.c:16) test_module
 
-在本例中,執行的代碼是從文件「~/linux-5.10.5/test-module/test-module.c」構建的,
+在本例中,執行的代碼是從文件“~/linux-5.10.5/test-module/test-module.c”構建的,
 錯誤出現在第16行的指令中。
 
-該腳本也會如此解碼以「Call trace」開頭的部分中提到的地址,該部分顯示出現問題的
+該腳本也會如此解碼以“Call trace”開頭的部分中提到的地址,該部分顯示出現問題的
 函數的路徑。此外,腳本還會顯示內核正在執行的代碼部分的彙編輸出。
 
 注意,如果你沒法做到這一點,只需跳過這一步,並在報告中說明原因。如果你幸運的
@@ -790,60 +785,60 @@ CONFIG_DEBUG_INFO 和 CONFIG_KALLSYMS選項時,這種方法才起效。如果
 別擔心,如果您碰到的情況需要這樣做,開發人員會告訴您該怎麼做。
 
 
-對回歸的特別關照
+對迴歸的特別關照
 -----------------
 
-    *如果您的問題是回歸問題,請儘可能縮小引入問題時的範圍。*
+    *如果您的問題是迴歸問題,請儘可能縮小引入問題時的範圍。*
 
 Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這就是爲什麼他
-認爲回歸是不可接受的,並希望看到它們被迅速修復。這就是爲什麼引入了回歸的改
-動導致的問題若無法通過其他方式快速解決,通常會被迅速撤銷。因此,報告回歸有
-點像「王炸」,會迅速得到修復。但要做到這一點,需要知道導致回歸的變化。通常情
+認爲迴歸是不可接受的,並希望看到它們被迅速修復。這就是爲什麼引入了迴歸的改
+動導致的問題若無法通過其他方式快速解決,通常會被迅速撤銷。因此,報告迴歸有
+點像“王炸”,會迅速得到修復。但要做到這一點,需要知道導致迴歸的變化。通常情
 況下,要由報告者來追查罪魁禍首,因爲維護者往往沒有時間或手頭設置不便來自行
 重現它。
 
-有一個叫做「二分」的過程可以來尋找變化,這在
-「Documentation/translations/zh_TW/admin-guide/bug-bisect.rst」文檔中進行了詳細
+有一個叫做“二分”的過程可以來尋找變化,這在
+Documentation/translations/zh_CN/admin-guide/bug-bisect.rst 文檔中進行了詳細
 的描述,這個過程通常需要你構建十到二十個內核鏡像,每次都嘗試在構建下一個鏡像
-之前重現問題。是的,這需要花費一些時間,但不用擔心,它比大多數人想像的要快得多。
-多虧了「binary search二進位搜索」,這將引導你在原始碼管理系統中找到導致回歸的提交。
+之前重現問題。是的,這需要花費一些時間,但不用擔心,它比大多數人想象的要快得多。
+多虧了“binary search二分搜索”,這將引導你在源代碼管理系統中找到導致迴歸的提交。
 一旦你找到它,就在網上搜索其主題、提交ID和縮短的提交ID(提交ID的前12個字符)。
 如果有的話,這將引導您找到關於它的現有報告。
 
 需要注意的是,二分法需要一點竅門,不是每個人都懂得訣竅,也需要相當多的努力,
 不是每個人都願意投入。儘管如此,還是強烈建議自己進行一次二分。如果你真的
-不能或者不想走這條路,至少要找出是哪個主線內核引入的回歸。比如說從 5.5.15
+不能或者不想走這條路,至少要找出是哪個主線內核引入的迴歸。比如說從 5.5.15
 切換到 5.8.4 的時候出現了一些問題,那麼至少可以嘗試一下相近的所有的主線版本
 (5.6、5.7 和 5.8)來檢查它是什麼時候出現的。除非你想在一個穩定版或長期支持
-內核中找到一個回歸,否則要避免測試那些編號有三段的版本(5.6.12、5.7.8),因
-爲那會使結果難以解釋,可能會讓你的測試變得無用。一旦你找到了引入回歸的主要
+內核中找到一個迴歸,否則要避免測試那些編號有三段的版本(5.6.12、5.7.8),因
+爲那會使結果難以解釋,可能會讓你的測試變得無用。一旦你找到了引入迴歸的主要
 版本,就可以放心地繼續報告了。但請記住:在不知道罪魁禍首的情況下,開發人員
 是否能夠提供幫助取決於手頭的問題。有時他們可能會從報告中確認是什麼出現了問
 題,並能修復它;有時他們可能無法提供幫助,除非你進行二分。
 
-當處理回歸問題時,請確保你所面臨的問題真的是由內核引起的,而不是由其他東西
+當處理迴歸問題時,請確保你所面臨的問題真的是由內核引起的,而不是由其他東西
 引起的,如上文所述。
 
-在整個過程中,請記住:只有當舊內核和新內核的配置相似時,問題才算回歸。最好
-的方法是:把配置文件(``.config``)從舊的工作內核直接複製到你嘗試的每個新內
-核版本。之後運行 ``make oldnoconfig`` 來調整它以適應新版本的需要,而不啓用
-任何新的功能,因爲那些功能也可能導致回歸。
+在整個過程中,請記住:只有當舊內核和新內核的配置相似時,問題纔算迴歸。這可以
+通過 ``make olddefconfig`` 來實現,詳細解釋參見
+Documentation/admin-guide/reporting-regressions.rst ;它還提供了大量其他您
+可能希望瞭解的有關回歸的信息。
 
 
-撰寫並發送報告
+撰寫併發送報告
 ---------------
 
     *通過詳細描述問題來開始編寫報告。記得包括以下條目:您爲復現而安裝的最新
     內核版本、使用的Linux發行版以及關於如何復現該問題的說明。如果可能,將內
-    核構建配置(.config)和 ``dmesg`` 的輸出放在網上的某個地方,並連結到它。
+    核構建配置(.config)和 ``dmesg`` 的輸出放在網上的某個地方,並鏈接到它。
     包含或上傳所有其他可能相關的信息,如Oops的輸出/截圖或來自 ``lspci``
     的輸出。一旦你寫完了這個主要部分,請在上方插入一個正常長度的段落快速概
     述問題和影響。再在此之上添加一個簡單描述問題的句子,以得到人們的閱讀。
     現在給出一個更短的描述性標題或主題。然後就可以像MAINTAINERS文件告訴你的
-    那樣發送或提交報告了,除非你在處理一個「高優先級問題」:它們需要按照下面
-    「高優先級問題的特殊處理」所述特別關照。*
+    那樣發送或提交報告了,除非你在處理一個“高優先級問題”:它們需要按照下面
+    “高優先級問題的特殊處理”所述特別關照。*
 
-現在你已經準備好了一切,是時候寫你的報告了。上文前言中連結的三篇文檔對如何
+現在你已經準備好了一切,是時候寫你的報告了。上文前言中鏈接的三篇文檔對如何
 寫報告做了部分解釋。這就是爲什麼本文將只提到一些基本的內容以及 Linux 內核特
 有的東西。
 
@@ -855,7 +850,7 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 每份報告都應提及的事項
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
-詳細描述你的問題是如何發生在你安裝的新純淨內核上的。試著包含你之前寫的和優
+詳細描述你的問題是如何發生在你安裝的新純淨內核上的。試着包含你之前寫的和優
 化過的分步說明,概述你和其他人如何重現這個問題;在極少數無法重現的情況下,
 儘量描述你做了什麼來觸發它。
 
@@ -864,19 +859,19 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 
  * ``cat /proc/version`` 的輸出,其中包含 Linux 內核版本號和構建時的編譯器。
 
- * 機器正在運行的 Linux 發行版( ``hostnamectl | grep 「Operating System「`` )
+ * 機器正在運行的 Linux 發行版( ``hostnamectl | grep “Operating System“`` )
 
- * CPU 和作業系統的架構( ``uname -mi`` )
+ * CPU 和操作系統的架構( ``uname -mi`` )
 
- * 如果您正在處理回歸,並進行了二分,請提及導致回歸的變更的主題和提交ID。
+ * 如果您正在處理迴歸,並進行了二分,請提及導致迴歸的變更的主題和提交ID。
 
-許多情況下,讓讀你報告的人多了解兩件事也是明智之舉:
+許多情況下,讓讀你報告的人多瞭解兩件事也是明智之舉:
 
- * 用於構建 Linux 內核的配置(「.config」文件)
+ * 用於構建 Linux 內核的配置(“.config”文件)
 
- * 內核的信息,你從 ``dmesg`` 得到的信息寫到一個文件里。確保它以像「Linux
+ * 內核的信息,你從 ``dmesg`` 得到的信息寫到一個文件裏。確保它以像“Linux
    version 5.8-1 (foobar@example.com) (gcc (GCC) 10.2.1, GNU ld version
-   2.34) #1 SMP Mon Aug 3 14:54:37 UTC 2020」這樣的行開始,如果沒有,那麼第
+   2.34) #1 SMP Mon Aug 3 14:54:37 UTC 2020”這樣的行開始,如果沒有,那麼第
    一次啓動階段的重要信息已經被丟棄了。在這種情況下,可以考慮使用
    ``journalctl -b 0 -k`` ;或者你也可以重啓,重現這個問題,然後調用
    ``dmesg`` 。
@@ -887,39 +882,39 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 
  * 將文件上傳到某個公開的地方(你的網站,公共文件粘貼服務,在
    `bugzilla.kernel.org <https://bugzilla.kernel.org/>`_ 上創建的工單……),
-   並在你的報告中放上連結。理想情況下請使用允許這些文件保存很多年的地方,因
+   並在你的報告中放上鍊接。理想情況下請使用允許這些文件保存很多年的地方,因
    爲它們可能在很多年後對別人有用;例如 5 年或 10 年後,一個開發者正在修改
    一些代碼,而這些代碼正是爲了修復你的問題。
 
- * 把文件放在一邊,然後說明你會在他人回復時再單獨發送。只要記得報告發出去後,
+ * 把文件放在一邊,然後說明你會在他人回覆時再單獨發送。只要記得報告發出去後,
    真正做到這一點就可以了。;-)
 
 提供這些東西可能是明智的
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-根據問題的不同,你可能需要提供更多的背景數據。這裡有一些關於提供什麼比較好
+根據問題的不同,你可能需要提供更多的背景數據。這裏有一些關於提供什麼比較好
 的建議:
 
- * 如果你處理的是內核的「warning」、「OOPS」或「panic」,請包含它。如果你不能複製
-   粘貼它,試著用netconsole網絡終端遠程跟蹤或者至少拍一張屏幕的照片。
+ * 如果你處理的是內核的“warning”、“OOPS”或“panic”,請包含它。如果你不能複製
+   粘貼它,試着用netconsole網絡終端遠程跟蹤或者至少拍一張屏幕的照片。
 
- * 如果問題可能與你的電腦硬體有關,請說明你使用的是什麼系統。例如,如果你的
-   顯卡有問題,請提及它的製造商,顯卡的型號,以及使用的晶片。如果是筆記本電
-   腦,請提及它的型號名稱,但儘量確保意義明確。例如「戴爾 XPS 13」就不很明確,
+ * 如果問題可能與你的電腦硬件有關,請說明你使用的是什麼系統。例如,如果你的
+   顯卡有問題,請提及它的製造商,顯卡的型號,以及使用的芯片。如果是筆記本電
+   腦,請提及它的型號名稱,但儘量確保意義明確。例如“戴爾 XPS 13”就不很明確,
    因爲它可能是 2012 年的那款,那款除了看起來和現在銷售的沒有什麼不同之外,
    兩者沒有任何共同之處。因此,在這種情況下,要加上準確的型號,例如 2019
-   年內推出的 XPS 13 型號爲「9380」或「7390」。像「聯想 Thinkpad T590」這樣的名字
+   年內推出的 XPS 13 型號爲“9380”或“7390”。像“聯想 Thinkpad T590”這樣的名字
    也有些含糊不清:這款筆記本有帶獨立顯卡和不帶的子型號,所以要儘量找到準確
    的型號名稱或註明主要部件。
 
- * 說明正在使用的相關軟體。如果你在加載模塊時遇到了問題,你要說明正在使用的
+ * 說明正在使用的相關軟件。如果你在加載模塊時遇到了問題,你要說明正在使用的
    kmod、systemd 和 udev 的版本。如果其中一個 DRM 驅動出現問題,你要說明
    libdrm 和 Mesa 的版本;還要說明你的 Wayland 合成器或 X-Server 及其驅動。
    如果你有文件系統問題,請註明相應的文件系統實用程序的版本(e2fsprogs,
    btrfs-progs, xfsprogs……)。
 
  * 從內核中收集可能有用的額外信息。例如, ``lspci -nn`` 的輸出可以幫助別人
-   識別你使用的硬體。如果你的硬體有問題,你甚至可以給出 ``sudo lspci -vvv``
+   識別你使用的硬件。如果你的硬件有問題,你甚至可以給出 ``sudo lspci -vvv``
    的結果,因爲它提供了組件是如何配置的信息。對於一些問題,可能最好包含
    ``/proc/cpuinfo`` , ``/proc/ioports`` , ``/proc/iomem`` ,
    ``/proc/modules`` 或 ``/proc/scsi/scsi`` 等文件的內容。一些子系統還提
@@ -936,7 +931,7 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 ~~~~~~~~~~~~~~~~~~~~~~
 
 現在你已經準備好了報告的詳細部分,讓我們進入最重要的部分:開頭幾句。現在到
-報告的最前面,在你剛才寫的部分之前加上類似「The detailed description:」(詳細
+報告的最前面,在你剛纔寫的部分之前加上類似“The detailed description:”(詳細
 描述)這樣的內容,並在最前面插入兩個新行。現在寫一個正常長度的段落,大致概
 述這個問題。去掉所有枯燥的細節,把重點放在讀者需要知道的關鍵部分,以讓人了
 解這是怎麼回事;如果你認爲這個缺陷影響了很多用戶,就提一下這點來吸引大家關
@@ -946,10 +941,10 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 要更加抽象,爲報告寫一個更短的主題/標題。
 
 現在你已經寫好了這部分,請花點時間來優化它,因爲它是你的報告中最重要的部分:
-很多人會先讀這部分,然後才會決定是否值得花時間閱讀其他部分。
+很多人會先讀這部分,然後纔會決定是否值得花時間閱讀其他部分。
 
 現在就像 :ref:`MAINTAINERS <maintainers>` 維護者文件告訴你的那樣發送或提交
-報告,除非它是前面概述的那些「高優先級問題」之一:在這種情況下,請先閱讀下一
+報告,除非它是前面概述的那些“高優先級問題”之一:在這種情況下,請先閱讀下一
 小節,然後再發送報告。
 
 高優先級問題的特殊處理
@@ -960,11 +955,19 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 **非常嚴重的缺陷** :確保在主題或工單標題以及第一段中明顯標出 severeness
 (非常嚴重的)。
 
-**回歸** :如果問題是一個回歸,請在郵件的主題或缺陷跟蹤器的標題中添加
-[REGRESSION]。如果您沒有進行二分,請至少註明您測試的最新主線版本(比如 5.7)
-和出現問題的最新版本(比如 5.8)。如果您成功地進行了二分,請註明導致回歸
-的提交ID和主題。也請添加該變更的作者到你的報告中;如果您需要將您的缺陷提交
-到缺陷跟蹤器中,請將報告以私人郵件的形式轉發給他,並註明報告提交地點。
+**迴歸** :報告的主題應以“[REGRESSION]”開頭。
+
+如果您成功用二分法定位了問題,請使用引入迴歸之更改的標題作爲主題的第二部分。
+請在報告中寫明“罪魁禍首”的提交ID。如果未能成功二分,請在報告中講明最後一個
+正常工作的版本(例如5.7)和最先發生問題的版本(例如5.8-rc1)。
+
+通過郵件發送報告時,請抄送Linux迴歸郵件列表(regressions@lists.linux.dev)。
+如果報告需要提交到某個web追蹤器,請繼續提交;並在提交後,通過郵件將報告轉發
+至迴歸列表;抄送相關子系統的維護人員和郵件列表。請確保報告是內聯轉發的,不要
+把它作爲附件。另外請在頂部添加一個簡短的說明,在那裏寫上工單的網址。
+
+在郵寄或轉發報告時,如果成功二分,需要將“罪魁禍首”的作者添加到收件人中;同時
+抄送signed-off-by鏈中的每個人,您可以在提交消息的末尾找到。
 
 **安全問題** :對於這種問題,你將必須評估:如果細節被公開披露,是否會對其他
 用戶產生短期風險。如果不會,只需按照所述繼續報告問題。如果有此風險,你需要
@@ -972,47 +975,47 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 
  * 如果 MAINTAINERS 文件指示您通過郵件報告問題,請不要抄送任何公共郵件列表。
 
- * 如果你應該在缺陷跟蹤器中提交問題,請確保將工單標記爲「私有」或「安全問題」。
+ * 如果你應該在缺陷跟蹤器中提交問題,請確保將工單標記爲“私有”或“安全問題”。
    如果缺陷跟蹤器沒有提供保持報告私密性的方法,那就別想了,把你的報告以私人
    郵件的形式發送給維護者吧。
 
-在這兩種情況下,都一定要將報告發到 MAINTAINERS 文件中「安全聯絡」部分列出的
+在這兩種情況下,都一定要將報告發到 MAINTAINERS 文件中“安全聯絡”部分列出的
 地址。理想的情況是在發送報告的時候直接抄送他們。如果您在缺陷跟蹤器中提交了
-報告,請將報告的文本轉發到這些地址;但請在報告的頂部加上注釋,表明您提交了
-報告,並附上工單連結。
+報告,請將報告的文本轉發到這些地址;但請在報告的頂部加上註釋,表明您提交了
+報告,並附上工單鏈接。
 
-更多信息請參見「Documentation/translations/zh_TW/admin-guide/security-bugs.rst」。
+更多信息請參見 Documentation/translations/zh_CN/admin-guide/security-bugs.rst 。
 
 
-發布報告後的責任
+發佈報告後的責任
 ------------------
 
     *等待別人的反應,繼續推進事情,直到你能夠接受這樣或那樣的結果。因此,請
     公開和及時地回應任何詢問。測試提出的修復。積極地測試:至少重新測試每個
     新主線版本的首個候選版本(RC),並報告你的結果。如果出現拖延,就友好地
-    提醒一下。如果你沒有得到任何幫助或者未能滿意,請試著自己幫助自己。*
+    提醒一下。如果你沒有得到任何幫助或者未能滿意,請試着自己幫助自己。*
 
 如果你的報告非常優秀,而且你真的很幸運,那麼某個開發者可能會立即發現導致問
 題的原因;然後他們可能會寫一個補丁來修復、測試它,並直接發送給主線集成,同
-時標記它以便以後回溯到需要它的穩定版和長期支持內核。那麼你需要做的就是回復
-一句「Thank you very much」(非常感謝),然後在發布後換上修復好的版本。
+時標記它以便以後回溯到需要它的穩定版和長期支持內核。那麼你需要做的就是回覆
+一句“Thank you very much”(非常感謝),然後在發佈後換上修復好的版本。
 
-但這種理想狀況很少發生。這就是爲什麼你把報告拿出來之後工作才開始。你要做的
-事情要視情況而定,但通常會是下面列出的事情。但在深入研究細節之前,這裡有幾
+但這種理想狀況很少發生。這就是爲什麼你把報告拿出來之後工作纔開始。你要做的
+事情要視情況而定,但通常會是下面列出的事情。但在深入研究細節之前,這裏有幾
 件重要的事情,你需要記住這部分的過程。
 
 
 關於進一步互動的一般建議
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-**總是公開回復** :當你在缺陷跟蹤器中提交問題時,一定要在那裡回復,不要私下
-聯繫任何開發者。對於郵件報告,在回復您收到的任何郵件時,總是使用「全部回復」
+**總是公開回復** :當你在缺陷跟蹤器中提交問題時,一定要在那裏回覆,不要私下
+聯繫任何開發者。對於郵件報告,在回覆您收到的任何郵件時,總是使用“全部回覆”
 功能。這包括帶有任何你可能想要添加到你的報告中的額外數據的郵件:進入郵件應
-用程序「已發送」文件夾,並在郵件上使用「全部回復」來回復報告。這種方法可以確保
-公共郵件列表和其他所有參與者都能及時了解情況;它還能保持郵件線程的完整性,
+用程序“已發送”文件夾,並在郵件上使用“全部回覆”來回復報告。這種方法可以確保
+公共郵件列表和其他所有參與者都能及時瞭解情況;它還能保持郵件線程的完整性,
 這對於郵件列表將所有相關郵件歸爲一類是非常重要的。
 
-只有兩種情況不適合在缺陷跟蹤器或「全部回復」中發表評論:
+只有兩種情況不適合在缺陷跟蹤器或“全部回覆”中發表評論:
 
  * 有人讓你私下發東西。
 
@@ -1022,32 +1025,32 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 
 **在請求解釋或幫助之前先研究一下** :在這部分過程中,有人可能會告訴你用尚未
 掌握的技能做一些事情。例如你可能會被要求使用一些你從未聽說過的測試工具;或
-者你可能會被要求在 Linux 內核原始碼上應用一個補丁來測試它是否有幫助。在某些
-情況下,發個回復詢問如何做就可以了。但在走這條路之前,儘量通過在網際網路上搜
+者你可能會被要求在 Linux 內核源代碼上應用一個補丁來測試它是否有幫助。在某些
+情況下,發個回覆詢問如何做就可以了。但在走這條路之前,儘量通過在互聯網上搜
 索自行找到答案;或者考慮在其他地方詢問建議。比如詢問朋友,或者到你平時常去
 的聊天室或論壇發帖諮詢。
 
 **要有耐心** :如果你真的很幸運,你可能會在幾個小時內收到對你的報告的答覆。
 但大多數情況下會花費更多的時間,因爲維護者分散在全球各地,因此可能在不同的
-時區——在那裡他們已經享受著遠離鍵盤的夜晚。
+時區——在那裏他們已經享受着遠離鍵盤的夜晚。
 
 一般來說,內核開發者需要一到五個工作日來回復報告。有時會花費更長的時間,因
 爲他們可能正忙於合併窗口、其他工作、參加開發者會議,或者只是在享受一個漫長
 的暑假。
 
-「高優先級的問題」(見上面的解釋)例外:維護者應該儘快解決這些問題;這就是爲
+“高優先級的問題”(見上面的解釋)例外:維護者應該儘快解決這些問題;這就是爲
 什麼你應該最多等待一個星期(如果是緊急的事情,則只需兩天),然後再發送友好
 的提醒。
 
-有時維護者可能沒有及時回復;有時候可能會出現分歧,例如一個問題是否符合回歸
+有時維護者可能沒有及時回覆;有時候可能會出現分歧,例如一個問題是否符合迴歸
 的條件。在這種情況下,在郵件列表上提出你的顧慮,並請求其他人公開或私下回復
 如何繼續推進。如果失敗了,可能應該讓更高級別的維護者介入。如果是 WiFi 驅動,
 那就是無線維護者;如果沒有更高級別的維護者,或者其他一切努力都失敗了,那
 這可能是一種罕見的、可以讓 Linus Torvalds 參與進來的情況。
 
-**主動測試** :每當一個新的主線內核版本的第一個預發布版本(rc1)發布的時候,
+**主動測試** :每當一個新的主線內核版本的第一個預發佈版本(rc1)發佈的時候,
 去檢查一下這個問題是否得到了解決,或者是否有什麼重要的變化。在工單中或在
-回復報告的郵件中提及結果(確保所有參與討論的人都被抄送)。這將表明你的承諾
+回覆報告的郵件中提及結果(確保所有參與討論的人都被抄送)。這將表明你的承諾
 和你願意幫忙。如果問題持續存在,它也會提醒開發者確保他們不會忘記它。其他一
 些不定期的重新測試(例如用rc3、rc5 和最終版本)也是一個好主意,但只有在相關
 的東西發生變化或者你正在寫什麼東西的時候才報告你的結果。
@@ -1057,10 +1060,10 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 查詢和測試請求
 ~~~~~~~~~~~~~~~
 
-如果你的報告得到了回復則需履行以下責任:
+如果你的報告得到了回覆則需履行以下責任:
 
 **檢查與你打交道的人** :大多數情況下,會是維護者或特定代碼區域的開發人員對
-你的報告做出回應。但由於問題通常是公開報告的,所以回復的可能是任何人——包括
+你的報告做出回應。但由於問題通常是公開報告的,所以回覆的可能是任何人——包括
 那些想要幫忙的人,但最後可能會用他們的問題或請求引導你完全偏離軌道。這很少
 發生,但這是快速上網搜搜看你正在與誰互動是明智之舉的許多原因之一。通過這樣
 做,你也可以知道你的報告是否被正確的人聽到,因爲如果討論沒有導致滿意的問題
@@ -1086,63 +1089,63 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 報告到達時,維護者剛剛離開鍵盤一段時間,或者有更重要的事情要處理。在寫提醒
 信的時候,要善意地問一下,是否還需要你這邊提供什麼來讓事情推進下去。如果報
 告是通過郵件發出來的,那就在郵件的第一行回覆你的初始郵件(見上文),其中包
-括下方的原始報告的完整引用:這是少數幾種情況下,這樣的「TOFU」(Text Over,
+括下方的原始報告的完整引用:這是少數幾種情況下,這樣的“TOFU”(Text Over,
 Fullquote Under文字在上,完整引用在下)是正確的做法,因爲這樣所有的收件人都
 會以適當的順序立即讓細節到手頭上來。
 
-在提醒之後,再等三周的回覆。如果你仍然沒有得到適當的反饋,你首先應該重新考
+在提醒之後,再等三週的回覆。如果你仍然沒有得到適當的反饋,你首先應該重新考
 慮你的方法。你是否可能嘗試接觸了錯誤的人?是不是報告也許令人反感或者太混亂,
 以至於人們決定完全遠離它?排除這些因素的最好方法是:把報告給一兩個熟悉
 FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於如何繼續推進的建議。
-這可能意味著:準備一份更好的報告,讓這些人在你發出去之前對它進行審查。這樣
+這可能意味着:準備一份更好的報告,讓這些人在你發出去之前對它進行審查。這樣
 的方法完全可以;只需說明這是關於這個問題的第二份改進的報告,並附上第一份報
-告的連結。
+告的鏈接。
 
 如果報告是恰當的,你可以發送第二封提醒信;在其中詢問爲什麼報告沒有得到任何
-回復。第二封提醒郵件的好時機是在新 Linux 內核版本的首個預發布版本('rc1')
-發布後不久,因爲無論如何你都應該在那個時候重新測試並提供狀態更新(見上文)。
+回覆。第二封提醒郵件的好時機是在新 Linux 內核版本的首個預發佈版本('rc1')
+發佈後不久,因爲無論如何你都應該在那個時候重新測試並提供狀態更新(見上文)。
 
-如果第二次提醒的結果又在一周內沒有任何反應,可以嘗試聯繫上級維護者詢問意見:
+如果第二次提醒的結果又在一週內沒有任何反應,可以嘗試聯繫上級維護者詢問意見:
 即使再忙的維護者在這時候也至少應該發過某種確認。
 
 記住要做好失望的準備:理想狀況下維護者最好對每一個問題報告做出回應,但他們
-只有義務解決之前列出的「高優先級問題」。所以,如果你得到的回覆是「謝謝你的報告,
-我目前有更重要的問題要處理,在可預見的未來沒有時間去研究這個問題」,那請不
+只有義務解決之前列出的“高優先級問題”。所以,如果你得到的回覆是“謝謝你的報告,
+我目前有更重要的問題要處理,在可預見的未來沒有時間去研究這個問題”,那請不
 要太沮喪。
 
 也有可能在缺陷跟蹤器或列表中進行了一些討論之後,什麼都沒有發生,提醒也無助
 於激勵大家進行修復。這種情況可能是毀滅性的,但在 Linux 內核開發中確實會發生。
-這些和其他得不到幫助的原因在本文結尾處的「爲什麼有些問題在被報告後沒有得到
-任何回應或者仍然沒有修復」中進行了解釋。
+這些和其他得不到幫助的原因在本文結尾處的“爲什麼有些問題在被報告後沒有得到
+任何回應或者仍然沒有修復”中進行了解釋。
 
 如果你沒有得到任何幫助或問題最終沒有得到解決,不要沮喪:Linux 內核是 FLOSS,
-因此你仍然可以自己幫助自己。例如,你可以試著找到其他受影響的人,和他們一
+因此你仍然可以自己幫助自己。例如,你可以試着找到其他受影響的人,和他們一
 起合作來解決這個問題。這樣的團隊可以一起準備一份新的報告,提到團隊有多少人,
 爲什麼你們認爲這是應該得到解決的事情。也許你們還可以一起縮小確切原因或引
-入回歸的變化,這往往會使修復更容易。而且如果運氣好的話,團隊中可能會有懂點
-編程的人,也許能寫出一個修複方案。
+入迴歸的變化,這往往會使修復更容易。而且如果運氣好的話,團隊中可能會有懂點
+編程的人,也許能寫出一個修復方案。
 
 
 
-「報告穩定版和長期支持內核線的回歸」的參考
+“報告穩定版和長期支持內核線的迴歸”的參考
 ------------------------------------------
 
-本小節提供了在穩定版和長期支持內核線中面對回歸時需要執行的步驟的詳細信息。
+本小節提供了在穩定版和長期支持內核線中面對迴歸時需要執行的步驟的詳細信息。
 
 確保特定版本線仍然受支持
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
     *檢查內核開發人員是否仍然維護你關心的Linux內核版本線:去 kernel.org 的
-    首頁,確保此特定版本線的最新版沒有「[EOL]」標記。*
+    首頁,確保此特定版本線的最新版沒有“[EOL]”標記。*
 
 大多數內核版本線只支持三個月左右,因爲延長維護時間會帶來相當多的工作。因此,
 每年只會選擇一個版本來支持至少兩年(通常是六年)。這就是爲什麼你需要檢查
 內核開發者是否還支持你關心的版本線。
 
-注意,如果 `kernel.org <https://kernel.org/>`_ 在首頁上列出了兩個「穩定」版本,
+注意,如果 `kernel.org <https://kernel.org/>`_ 在首頁上列出了兩個“穩定”版本,
 你應該考慮切換到較新的版本,而忘掉較舊的版本:對它的支持可能很快就會結束。
-然後,它將被標記爲「生命周期結束」(EOL)。達到這個程度的版本線仍然會在
-`kernel.org <https://kernel.org/>`_ 首頁上被顯示一兩周,但不適合用於測試和
+然後,它將被標記爲“生命週期結束”(EOL)。達到這個程度的版本線仍然會在
+`kernel.org <https://kernel.org/>`_ 首頁上被顯示一兩週,但不適合用於測試和
 報告。
 
 搜索穩定版郵件列表
@@ -1158,57 +1161,63 @@ FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於
 用最新版本復現問題
 ~~~~~~~~~~~~~~~~~~~
 
-    *從特定的版本線安裝最新版本作爲純淨內核。確保這個內核沒有被汙染,並且仍
-    然存在問題,因爲問題可能已經在那裡被修復了。*
+    *從特定的版本線安裝最新版本作爲純淨內核。確保這個內核沒有被污染,並且仍
+    然存在問題,因爲問題可能已經在那裏被修復了。*
 
 在投入更多時間到這個過程中之前,你要檢查這個問題是否在你關注的版本線的最新
-版本中已經得到了修復。這個內核需要是純淨的,在問題發生之前不應該被汙染,正
+版本中已經得到了修復。這個內核需要是純淨的,在問題發生之前不應該被污染,正
 如上面已經在測試主線的過程中詳細介紹過的一樣。
 
-您是否是第一次注意到供應商內核的回歸?供應商的更改可能會發生變化。你需要重新
+您是否是第一次注意到供應商內核的迴歸?供應商的更改可能會發生變化。你需要重新
 檢查排除來這個問題。當您從5.10.4-vendor.42更新到5.10.5-vendor.43時,記錄損壞
 的信息。然後在測試了前一段中所述的最新5.10版本之後,檢查Linux 5.10.4的普通版本
-是否也可以正常工作。如果問題在那裡出現,那就不符合上游回歸的條件,您需要切換
+是否也可以正常工作。如果問題在那裏出現,那就不符合上游迴歸的條件,您需要切換
 回主逐步指南來報告問題。
 
-報告回歸
+報告迴歸
 ~~~~~~~~~~
 
-    *向Linux穩定版郵件列表發送一個簡短的問題報告(stable@vger.kernel.org)。
-    大致描述問題,並解釋如何復現。講清楚首個出現問題的版本和最後一個工作正常
-    的版本。然後等待進一步的指示。*
+    *向Linux穩定版郵件列表發送一個簡短的問題報告(stable@vger.kernel.org)並
+    抄送Linux迴歸郵件列表(regressions@lists.linux.dev);如果你懷疑是由某
+    子系統引起的,請抄送其維護人員和子系統郵件列表。大致描述問題,並解釋如
+    何復現。講清楚首個出現問題的版本和最後一個工作正常的版本。然後等待進一
+    步的指示。*
 
-當報告在穩定版或長期支持內核線內發生的回歸(例如在從5.10.4更新到5.10.5時),
-一份簡短的報告足以快速報告問題。因此只需要粗略的描述。
+當報告在穩定版或長期支持內核線內發生的迴歸(例如在從5.10.4更新到5.10.5時),
+一份簡短的報告足以快速報告問題。因此只需向穩定版和迴歸郵件列表發送粗略的描述;
+不過如果你懷疑某子系統導致此問題的話,請一併抄送其維護人員和子系統郵件列表,
+這會加快進程。
 
-但是請注意,如果您能夠指明引入問題的確切版本,這將對開發人員有很大幫助。因此
-如果有時間的話,請嘗試使用普通內核找到該版本。讓我們假設發行版發布Linux內核
+請注意,如果您能夠指明引入問題的確切版本,這將對開發人員有很大幫助。因此
+如果有時間的話,請嘗試使用普通內核找到該版本。讓我們假設發行版發佈Linux內核
 5.10.5到5.10.8的更新時發生了故障。那麼按照上面的指示,去檢查該版本線中的最新
 內核,比如5.10.9。如果問題出現,請嘗試普通5.10.5,以確保供應商應用的補丁不會
 干擾。如果問題沒有出現,那麼嘗試5.10.7,然後直到5.10.8或5.10.6(取決於結果)
 找到第一個引入問題的版本。在報告中寫明這一點,並指出5.10.9仍然存在故障。
 
-前一段基本粗略地概述了「二分」方法。一旦報告出來,您可能會被要求做一個正確的
+前一段基本粗略地概述了“二分”方法。一旦報告出來,您可能會被要求做一個正確的
 報告,因爲它允許精確地定位導致問題的確切更改(然後很容易被恢復以快速修復問題)。
-因此如果時間允許,考慮立即進行適當的二分。有關如何詳細信息,請參閱「對回歸的
-特別關照」部分和文檔「Documentation/translations/zh_TW/admin-guide/bug-bisect.rst」。
+因此如果時間允許,考慮立即進行適當的二分。有關如何詳細信息,請參閱“對迴歸的
+特別關照”部分和文檔 Documentation/translations/zh_CN/admin-guide/bug-bisect.rst 。
+如果成功二分的話,請將“罪魁禍首”的作者添加到收件人中;同時抄送所有在
+signed-off-by鏈中的人,您可以在提交消息的末尾找到。
 
 
-「報告僅在舊內核版本線中發生的問題」的參考
-------------------------------------------
+“報告僅在舊內核版本線中發生的問題”的參考
+----------------------------------------
 
-本節詳細介紹了如果無法用主線內核重現問題,但希望在舊版本線(又稱穩定版內核和
+本節詳細介紹瞭如果無法用主線內核重現問題,但希望在舊版本線(又稱穩定版內核和
 長期支持內核)中修復問題時需要採取的步驟。
 
 有些修復太複雜
 ~~~~~~~~~~~~~~~
 
     *請做好準備,接下來的幾個步驟可能無法在舊版本中解決問題:修復可能太大或
-    太冒險,無法移植到那裡。*
+    太冒險,無法移植到那裏。*
 
 即使是微小的、看似明顯的代碼變化,有時也會帶來新的、完全意想不到的問題。穩
 定版和長期支持內核的維護者非常清楚這一點,因此他們只對這些內核進行符合
-「Documentation/translations/zh_TW/process/stable-kernel-rules.rst」中所列出的
+Documentation/translations/zh_CN/process/stable-kernel-rules.rst 中所列出的
 規則的修改。
 
 複雜或有風險的修改不符合條件,因此只能應用於主線。其他的修復很容易被回溯到
@@ -1220,7 +1229,7 @@ FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於
 通用準備
 ~~~~~~~~~~
 
-    *執行上面「報告僅在舊內核版本線中發生的問題」一節中的前三個步驟。*
+    *執行上面“報告僅在舊內核版本線中發生的問題”一節中的前三個步驟。*
 
 您需要執行本指南另一節中已經描述的幾個步驟。這些步驟將讓您:
 
@@ -1242,21 +1251,21 @@ FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於
 在許多情況下,你所處理的問題會發生在主線上,但已在主線上得到了解決。修正它
 的提交也需要被回溯才能解決這個問題。這就是爲什麼你要搜索它或任何相關討論。
 
- * 首先嘗試在存放 Linux 內核原始碼的 Git 倉庫中找到修復。你可以通過
+ * 首先嚐試在存放 Linux 內核源代碼的 Git 倉庫中找到修復。你可以通過
    `kernel.org 上的網頁
    <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/>`_
    或 `GitHub 上的鏡像 <https://github.com/torvalds/linux>`_ 來實現;如果你
    有一個本地克隆,你也可以在命令行用 ``git log --grep=<pattern>`` 來搜索。
 
-   如果你找到了修復,請查看提交消息的尾部是否包含了類似這樣的「穩定版標籤」:
+   如果你找到了修復,請查看提交消息的尾部是否包含了類似這樣的“穩定版標籤”:
 
           Cc: <stable@vger.kernel.org> # 5.4+
 
    像上面這行,開發者標記了安全修復可以回傳到 5.4 及以後的版本。大多數情況
-   下,它會在兩周內被應用到那裡,但有時需要更長的時間。
+   下,它會在兩週內被應用到那裏,但有時需要更長的時間。
 
  * 如果提交沒有告訴你任何東西,或者你找不到修復,請再找找關於這個問題的討論。
-   用你最喜歡的搜尋引擎搜索網絡,以及 `Linux kernel developers mailing
+   用你最喜歡的搜索引擎搜索網絡,以及 `Linux kernel developers mailing
    list 內核開發者郵件列表 <https://lore.kernel.org/lkml/>`_ 的檔案。也可以
    閱讀上面的 `定位導致問題的內核區域` 一節,然後按照說明找到導致問題的子系
    統:它的缺陷跟蹤器或郵件列表存檔中可能有你要找的答案。
@@ -1286,41 +1295,41 @@ FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於
 爲什麼有些問題在報告後沒有任何回應或仍未解決?
 ===============================================
 
-當向 Linux 開發者報告問題時,要注意只有「高優先級的問題」(回歸、安全問題、嚴
+當向 Linux 開發者報告問題時,要注意只有“高優先級的問題”(迴歸、安全問題、嚴
 重問題)才一定會得到解決。如果維護者或其他人都失敗了,Linus Torvalds 他自己
 會確保這一點。他們和其他內核開發者也會解決很多其他問題。但是要知道,有時他
 們也會不能或不願幫忙;有時甚至沒有人發報告給他們。
 
 最好的解釋就是那些內核開發者常常是在業餘時間爲 Linux 內核做出貢獻。內核中的
-不少驅動程序都是由這樣的程式設計師編寫的,往往只是因爲他們想讓自己的硬體可以在
-自己喜歡的作業系統上使用。
+不少驅動程序都是由這樣的程序員編寫的,往往只是因爲他們想讓自己的硬件可以在
+自己喜歡的操作系統上使用。
 
-這些程式設計師大多數時候會很樂意修復別人報告的問題。但是沒有人可以強迫他們這樣
+這些程序員大多數時候會很樂意修復別人報告的問題。但是沒有人可以強迫他們這樣
 做,因爲他們是自願貢獻的。
 
 還有一些情況下,這些開發者真的很想解決一個問題,但卻不能解決:有時他們缺乏
-硬體編程文檔來解決問題。這種情況往往由於公開的文檔太簡陋,或者驅動程序是通
+硬件編程文檔來解決問題。這種情況往往由於公開的文檔太簡陋,或者驅動程序是通
 過逆向工程編寫的。
 
-業餘開發者遲早也會不再關心某驅動。也許他們的測試硬體壞了,被更高級的玩意取
-代了,或者是太老了以至於只能在計算機博物館裡找到。有時開發者根本就不關心他
+業餘開發者遲早也會不再關心某驅動。也許他們的測試硬件壞了,被更高級的玩意取
+代了,或者是太老了以至於只能在計算機博物館裏找到。有時開發者根本就不關心他
 們的代碼和 Linux 了,因爲在他們的生活中一些不同的東西變得更重要了。在某些情
 況下,沒有人願意接手維護者的工作——也沒有人可以被強迫,因爲對 Linux 內核的貢
 獻是自願的。然而被遺棄的驅動程序仍然存在於內核中:它們對人們仍然有用,刪除
-它們可能導致回歸。
+它們可能導致迴歸。
 
 對於那些爲 Linux 內核工作而獲得報酬的開發者來說,情況並沒有什麼不同。這些人
 現在貢獻了大部分的變更。但是他們的僱主遲早也會停止關注他們的代碼或者讓程序
-員專注於其他事情。例如,硬體廠商主要通過銷售新硬體來賺錢;因此,他們中的不
+員專注於其他事情。例如,硬件廠商主要通過銷售新硬件來賺錢;因此,他們中的不
 少人並沒有投入太多時間和精力來維護他們多年前就停止銷售的東西的 Linux 內核驅
 動。企業級 Linux 發行商往往持續維護的時間比較長,但在新版本中往往會把對老舊
-和稀有硬體的支持放在一邊,以限制範圍。一旦公司拋棄了一些代碼,往往由業餘貢
+和稀有硬件的支持放在一邊,以限制範圍。一旦公司拋棄了一些代碼,往往由業餘貢
 獻者接手,但正如上面提到的:他們遲早也會放下代碼。
 
 優先級是一些問題沒有被修復的另一個原因,因爲維護者相當多的時候是被迫設置這
 些優先級的,因爲在 Linux 上工作的時間是有限的。對於業餘時間或者僱主給予他們
 的開發人員用於上游內核維護工作的時間也是如此。有時維護人員也會被報告淹沒,
-即使一個驅動程序幾乎完美地工作。爲了不被完全纏住,程式設計師可能別無選擇,只能
+即使一個驅動程序幾乎完美地工作。爲了不被完全纏住,程序員可能別無選擇,只能
 對問題報告進行優先級排序而拒絕其中的一些報告。
 
 不過這些都不用太過擔心,很多驅動都有積極的維護者,他們對儘可能多的解決問題
@@ -1330,8 +1339,32 @@ FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於
 結束語
 =======
 
-與其他免費/自由&開源軟體(Free/Libre & Open Source Software,FLOSS)相比,
-向 Linux 內核開發者報告問題是很難的:這個文檔的長度和複雜性以及字裡行間的內
+與其他免費/自由&開源軟件(Free/Libre & Open Source Software,FLOSS)相比,
+向 Linux 內核開發者報告問題是很難的:這個文檔的長度和複雜性以及字裏行間的內
 涵都說明了這一點。但目前就是這樣了。這篇文字的主要作者希望通過記錄現狀來爲
 以後改善這種狀況打下一些基礎。
 
+
+..
+   end-of-content
+..
+   This English version of this document is maintained by Thorsten Leemhuis
+   <linux@leemhuis.info>. If you spot a typo or small mistake, feel free to
+   let him know directly and he'll fix it. For translation problems, please
+   contact with translators. You are free to do the same in a mostly informal
+   way if you want to contribute changes to the text, but for copyright
+   reasons please CC linux-doc@vger.kernel.org and "sign-off" your
+   contribution as Documentation/process/submitting-patches.rst outlines in
+   the section "Sign your work - the Developer's Certificate of Origin".
+..
+   This text is available under GPL-2.0+ or CC-BY-4.0, as stated at the top
+   of the file. If you want to distribute this text under CC-BY-4.0 only,
+   please use "The Linux kernel developers" for author attribution and link
+   this as source:
+   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/reporting-issues.rst
+..
+   Note: Only the content of this RST file as found in the Linux kernel sources
+   is available under CC-BY-4.0, as versions of this text that were processed
+   (for example by the kernel's build system) might contain content taken from
+   files which use a more restrictive license.
+
diff --git a/Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst b/Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst
new file mode 100644
index 000000000000..d7dcb2a26564
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst
@@ -0,0 +1,371 @@
+.. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0)
+.. 【重分發信息參見本文件結尾】
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/reporting-regressions.rst
+
+:譯者:
+
+ 吳想成 Wu XiangCheng <bobwxc@email.cn>
+
+
+============
+報告迴歸問題
+============
+
+“*我們拒絕出現迴歸*”是Linux內核開發的首要規則;Linux的發起者和領軍開發者Linus
+Torvalds立下了此規則並確保它被落實。
+
+本文檔描述了這條規則對用戶的意義,以及Linux內核開發模型如何確保解決所有被報告
+的迴歸;關於內核開發者如何處理的方面參見 Documentation/process/handling-regressions.rst 。
+
+
+本文重點(亦即“太長不看”)
+==========================
+
+#. 如果某程序在原先的Linux內核上運行良好,但在較新版本上效果更差、或者根本不
+   能用,那麼你就碰見迴歸問題了。注意,新內核需要使用類似配置編譯;更多相關細
+   節參見下方。
+
+#. 按照 Documentation/translations/zh_CN/admin-guide/reporting-issues.rst 中
+   所說的報告你的問題,該文檔已經包含了所有關於迴歸的重要方面,爲了方便起見也
+   複製到了下面。兩個重點:在報告主題中使用“[REGRESSION]”開頭並抄送或轉發到
+   `迴歸郵件列表 <https://lore.kernel.org/regressions/>`_
+   (regressions@lists.linux.dev)。
+
+#. 可選但是建議:在發送或轉發報告時,指明該回歸發生的起點,以便Linux內核迴歸
+   追蹤機器人“regzbot”可以追蹤此問題::
+
+       #regzbot introduced v5.13..v5.14-rc1
+
+
+與用戶相關的所有Linux內核迴歸細節
+=================================
+
+
+基本重點
+--------
+
+
+什麼是“迴歸”以及什麼是“無迴歸規則”?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+如果某程序/實例在原先的Linux內核上運行良好,但在較新版本上效果更差、或者根本
+不能用,那麼你就碰見迴歸問題了。“無迴歸規則”不允許出現這種情況。如果偶然發
+生了,導致問題的開發者應當迅速修復問題。
+
+也就是說,若Linux 5.13中的WiFi驅動程序運行良好,但是在5.14版本上卻不能用、速
+度明顯變慢或出現錯誤,那就出現了迴歸。如果某正常工作的應用程序突然在新內核上
+出現不穩定,這也是迴歸;這些問題可能是由於procfs、sysfs或Linux提供給用戶空間
+軟件的許多其他接口之一的變化。但請記住,前述例子中的5.14需要使用類似於5.13的
+配置構建。這可以用 ``make olddefconfig`` 實現,詳細解釋見下。
+
+注意本節第一句話中的“實例”:即使開發者需要遵循“無迴歸”規則,但仍可自由地改
+變內核的任何方面,甚至是導出到用戶空間的API或ABI,只要別破壞現有的應用程序或
+用例。
+
+還需注意,“無迴歸”規則只限制內核提供給用戶空間的接口。它不適用於內核內部接
+口,比如一些外部開發的驅動程序用來插入鉤子到內核的模塊API。
+
+如何報告迴歸?
+~~~~~~~~~~~~~~
+
+只需按照 Documentation/translations/zh_CN/admin-guide/reporting-issues.rst 中
+所說的報告你的問題,該文檔已經包含了要點。下面幾點概述了一下只在迴歸中重要的
+方面:
+
+ * 在檢查可加入討論的現有報告時,別忘了搜索 `Linux迴歸郵件列表
+   <https://lore.kernel.org/regressions/>`_ 和 `regzbot網頁界面
+   <https://linux-regtracking.leemhuis.info/regzbot/>`_ 。
+
+ * 在報告主題的開頭加上“[REGRESSION]”。
+
+ * 在你的報告中明確最後一個正常工作的內核版本和首個出問題的版本。如若可能,
+   用二分法嘗試找出導致迴歸的變更,更多細節見下。
+
+ * 記得把報告發到Linux迴歸郵件列表(regressions@lists.linux.dev)。
+
+   * 如果通過郵件報告迴歸,請抄送回歸列表。
+
+   * 如果你使用某些缺陷追蹤器報告迴歸,請通過郵件轉發已提交的報告到迴歸列表,
+     並抄送維護者以及出問題的相關子系統的郵件列表。
+
+   如果是穩定版或長期支持版系列(如v5.15.3…v5.15.5)的迴歸,請記得抄送
+   `Linux穩定版郵件列表 <https://lore.kernel.org/stable/>`_ (stable@vger.kernel.org)。
+
+  如果你成功地執行了二分,請抄送肇事提交的信息中所有簽了“Signed-off-by:”的人。
+
+在抄送你的報告到列表時,也請記得通知前述的Linux內核迴歸追蹤機器人。只需在郵件
+中包含如下片段::
+
+       #regzbot introduced: v5.13..v5.14-rc1
+
+Regzbot會就將你的郵件視爲在某個特定版本區間的迴歸報告。上例中即linux v5.13仍
+然正常,而Linux 5.14-rc1是首個您遇到問題的版本。如果你執行了二分以查找導致回
+歸的提交,請使用指定肇事提交的id代替::
+
+       #regzbot introduced: 1f2e3d4c5d
+
+添加這樣的“regzbot命令”對你是有好處的,它會確保報告不會被忽略。如果你省略了
+它,Linux內核的迴歸跟蹤者會把你的迴歸告訴regzbot,只要你發送了一個副本到迴歸
+郵件列表。但是迴歸跟蹤者只有一個人,有時不得不休息或甚至偶爾享受可以遠離電腦
+的時光(聽起來很瘋狂)。因此,依賴此人手動將回歸添加到 `已追蹤且尚未解決的
+Linux內核迴歸列表 <https://linux-regtracking.leemhuis.info/regzbot/>`_ 和
+regzbot發送的每週迴歸報告,可能會出現延遲。 這樣的延誤會導致Linus Torvalds
+在決定“繼續開發還是發佈新版本?”時忽略嚴重的迴歸。
+
+真的修復了所有的迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+幾乎所有都是,只要引起問題的變更(肇事提交)被可靠定位。也有些迴歸可以不用這
+樣,但通常是必須的。
+
+誰需要找出迴歸的根本原因?
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+受影響代碼區域的開發者應該自行嘗試定位問題所在。但僅靠他們的努力往往是不可
+能做到的,很多問題只發生在開發者的無法接觸的其他特定外部環境中——例如特定的
+硬件平臺、固件、Linux發行版、系統的配置或應用程序。這就是爲什麼最終往往是報
+告者定位肇事提交;有時用戶甚至需要再運行額外測試以查明確切的根本原因。開發
+者應該提供建議和可能的幫助,以使普通用戶更容易完成該流程。
+
+如何找到罪魁禍首?
+~~~~~~~~~~~~~~~~~~
+
+如 Documentation/translations/zh_CN/admin-guide/reporting-issues.rst (簡要)
+和 Documentation/translations/zh_CN/admin-guide/bug-bisect.rst (詳細)中所
+述,執行二分。聽起來工作量很大,但大部分情況下很快就能找到罪魁禍首。如果這很
+困難或可靠地重現問題很耗時,請考慮與其他受影響的用戶合作,一起縮小搜索範圍。
+
+當出現迴歸時我可以向誰尋求建議?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+發送郵件到迴歸郵件列表(regressions@lists.linux.dev)同時抄送Linux內核的迴歸
+跟蹤者(regressions@leemhuis.info);如果問題需要保密處理,可以省略列表。
+
+
+關於迴歸的更多細節
+------------------
+
+
+“無迴歸規則”的目標是什麼?
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+用戶應該放心升級內核版本,而不必擔心有程序可能崩潰。這符合內核開發者的利益,
+可以使更新有吸引力:他們不希望用戶停留在停止維護或超過一年半的穩定/長期Linux
+版本系列上。這也符合所有人的利益,因爲 `那些系列可能含有已知的缺陷、安全問題
+或其他後續版本已經修復的問題
+<http://www.kroah.com/log/blog/2018/08/24/what-stable-kernel-should-i-use/>`_ 。
+此外,內核開發者希望使用戶測試最新的預發行版或常規發行版變得簡單而有吸引力。
+這同樣符合所有人的利益,如果新版本出來後很快就有相關報告,會使追蹤和修復問題
+更容易。
+
+實際中“無迴歸”規則真的可行嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+這不是句玩笑話,請見Linux創建者和主要開發人員Linus Torvalds在郵件列表中的許
+多發言,其中一些在 Documentation/process/handling-regressions.rst 中被引用。
+
+此規則的例外情況極爲罕見;之前當開發者認爲某個特定的情況有必要援引例外時,
+基本都被證明錯了。
+
+誰來確保“無迴歸”被落實?
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+照看和支撐樹的子系統維護者應該關心這一點——例如,Linus Torvalds之於主線,
+Greg Kroah-Hartman等人之於各種穩定/長期系列。
+
+他們都得到了別人的幫助,以確保迴歸報告不會被遺漏。其中之一是Thorsten
+Leemhuis,他目前擔任Linux內核的“迴歸跟蹤者”;爲了做好這項工作,他使用了
+regzbot——Linux內核迴歸跟蹤機器人。所以這就是爲什麼要抄送或轉發你的報告到
+迴歸郵件列表來通知這些人,已經最好在你的郵件中包含“regzbot命令”來立即追蹤它。
+
+迴歸通常多久能修復?
+~~~~~~~~~~~~~~~~~~~~
+
+開發者應該儘快修復任何被報告的迴歸,以提供及時爲受影響的用戶提供解決方案,並
+防止更多用戶遇到問題;然而,開發人員需要花足夠的時間和注意力確保迴歸修復不會
+造成額外的損害。
+
+因此,答案取決於各種因素,如迴歸的影響、存在時長或出現於哪個Linux版本系列。
+但最終,大多數的迴歸應該在兩週內修復。
+
+當問題可以通過升級某些軟件解決時,是迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+基本都是。如果開發人員告訴您其他情況,請諮詢上述迴歸跟蹤者。
+
+當新內核變慢或能耗增加,是迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+是的,但有一些差別。在微型基準測試中變慢5%不太可能被視爲迴歸,除非它也會對
+廣泛基準測試的結果產生超過1%的影響。如果有疑問,請尋求建議。
+
+當更新Linux時外部內核模塊崩潰了,是迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+不,因爲“無迴歸”規則僅限於Linux內核提供給用戶空間的接口和服務。因此,它不包括
+構建或運行外部開發的內核模塊,因爲它們在內核空間中運行與掛進內核使用的內部接
+口偶爾會變化。
+
+如何處理安全修復引起的迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+在極爲罕見的情況下,安全問題無法在不引起迴歸的情況下修復;這些修復都被放棄了,
+因爲它們終究會引起問題。幸運的是這種兩難境地基本都可以避免,受影響區域的主要
+開發者以及Linus Torvalds本人通常都會努力在不引入迴歸的情況下解決安全問題。
+
+如果你仍然面臨此種情況,請查看郵件列表檔案是否有人盡力避免過迴歸。如果沒有,
+請報告它;如有疑問,請如上所述尋求建議。
+
+當修復迴歸時不可避免會引入另一個,如何處理?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+很遺憾這種事確實會出現,但幸運的是並不經常出現;如果發生了,受影響代碼區的資
+深開發者應當調查該問題以找到避免迴歸的解決方法,至少避免它們的影響。如果你遇
+到這樣的情況,如上所述:檢查之前的討論是否有人已經盡了最大努力,如有疑問請尋
+求建議。
+
+小提示:如果人們在每個開發週期中定期給出主線預發佈(即v5.15-rc1或-rc3)以供
+測試,則可以避免這種情況。爲了更好地解釋,可以設想一個在Linux v5.14和v5.15-rc1
+之間集成的更改,該更改導致了迴歸,但同時是應用於5.15-rc1的其他改進的強依賴。
+如果有人在5.15發佈之前就發現並報告了這個問題,那麼所有更改都可以直接撤銷,從
+而解決迴歸問題。而就在幾天或幾周後,此解決方案變成了不可能,因爲一些軟件可能
+已經開始依賴於後續更改之一:撤銷所有更改將導致上述用戶軟件出現迴歸,這是不可
+接受的。
+
+若我所依賴的功能在數月前被移除了,是迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+是的,但如前節所述,通常很難修復此類迴歸。因此需要逐案處理。這也是定期測試主
+線預發佈對所有人有好處的另一個原因。
+
+如果我似乎是唯一受影響的人,是否仍適用“無迴歸”規則?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+適用,但僅限於實際使用:Linux開發人員希望能夠自由地取消那些只能在閣樓和博物
+館中找到的硬件的支持。
+
+請注意,有時爲了取得進展,不得不出現迴歸——後者也是防止Linux停滯不前所必需
+的。因此如果迴歸所影響的用戶很少,那麼爲了他們和其他人更大的利益,還是讓事情
+過去吧。尤其是存在某種規避迴歸的簡單方法,例如更新一些軟件或者使用專門爲此目
+的創建的內核參數。
+
+迴歸規則是否也適用於staging樹中的代碼?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+不,參見 `適用於所有staging代碼配置選項的幫助文本
+<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/staging/Kconfig>`_ ,
+其早已聲明::
+
+       請注意:這些驅動正在積極開發中,可能無法正常工作,並可能包含會在不久的
+       將來發生變化的用戶接口。
+
+雖然staging開發人員通常堅持“無迴歸”的原則,但有時爲了取得進展也會違背它。這就
+是爲什麼當staging樹的WiFi驅動被基本推倒重來時,有些用戶不得不處理迴歸(通常可
+以忽略)。
+
+爲什麼較新版本必須“使用相似配置編譯”?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+因爲Linux內核開發人員有時會集成已知的會導致迴歸的變更,但使它們成爲可選的,並
+在內核的默認配置下禁用它們。這一技巧允許進步,否則“無迴歸”規則將導致停滯。
+
+例如,試想一個新的可以阻止惡意軟件濫用某個內核的接口的安全特性,同時又需要滿足
+另一個很罕見的應用程序。上述的方法可使兩方都滿意:使用這些應用程序的人可以關閉
+新的安全功能,而其他不會遇到麻煩的人可以啓用它。
+
+如何創建與舊內核相似的配置?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+用一個已知良好的內核啓動機器,並用 ``make olddefconfig`` 配置新版的Linux。這
+會讓內核的構建腳本從正在運行的內核中摘錄配置文件(“.config”文件),作爲即將編
+譯的新版本的基礎配置;同時將所有新的配置選項設爲默認值,以禁用可能導致迴歸的
+新功能。
+
+如何報告在預編譯的普通內核中發現的迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+您需要確保新的內核是用與舊版相似的配置編譯(見上文),因爲那些構建它們的人可
+能啓用了一些已知的與新內核不兼容的特性。如有疑問,請向內核的提供者報告問題並
+尋求建議。
+
+
+用“regzbot”追蹤迴歸的更多信息
+-----------------------------
+
+什麼是迴歸追蹤?爲啥我需要關心它?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+像“無迴歸”這樣的規則需要有人來確保它們被遵守,否則會被有意/無意打破。歷史證
+明瞭這一點對於Linux內核開發也適用。這就是爲什麼Linux內核的迴歸跟蹤者Thorsten
+Leemhuis,,和另一些人盡力關注所有的迴歸直到他們解決。他們從未爲此獲得報酬,
+因此這項工作是在盡最大努力的基礎上完成的。
+
+爲什麼/如何使用機器人追蹤Linux內核迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+由於Linux內核開發過程的分佈式和鬆散結構,完全手動跟蹤迴歸已經被證明是相當困難
+的。因此Linux內核的迴歸跟蹤者開發了regzbot來促進這項工作,其長期目標是儘可能爲
+所有相關人員自動化迴歸跟蹤。
+
+Regzbot通過監視跟蹤的迴歸報告的回覆來工作。此外,它還查找用“Link:”標籤引用這
+些報告的補丁;對這些補丁的回覆也會被跟蹤。結合這些數據,可以很好地瞭解當前修
+復過程的狀態。
+
+如何查看regzbot當前追蹤的迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+參見 `regzbot在線 <https://linux-regtracking.leemhuis.info/regzbot/>`_ 。
+
+何種問題可以由regzbot追蹤?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+該機器人只爲了跟蹤迴歸,因此請不要讓regzbot涉及常規問題。但是對於Linux內核的
+迴歸跟蹤者來說,讓regzbot跟蹤嚴重問題也可以,如有關掛起、損壞數據或內部錯誤
+(Panic、Oops、BUG()、warning…)的報告。
+
+如何修改被追蹤迴歸的相關信息?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+在直接或間接回復報告郵件時使用“regzbot命令”即可。最簡單的方法是:在“已發送”文
+件夾或郵件列表存檔中找到報告,然後使用郵件客戶端的“全部回覆”功能對其進行回覆。
+在該郵件中的獨立段落中可使用以下命令之一(即使用空行將這些命令中的一個或多個與
+其餘郵件文本分隔開)。
+
+ * 更新迴歸引入起點,例如在執行二分之後::
+
+       #regzbot introduced: 1f2e3d4c5d
+
+ * 設置或更新標題::
+
+       #regzbot title: foo
+
+ * 監視討論或bugzilla.kernel.org上有關討論或修復的工單::
+
+       #regzbot monitor: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/
+       #regzbot monitor: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
+
+ * 標記一個有更多相關細節的地方,例如有關但主題不同的郵件列表帖子或缺陷追蹤器中的工單::
+
+       #regzbot link: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
+
+ * 標記迴歸已失效::
+
+       #regzbot invalid: wasn't a regression, problem has always existed
+
+Regzbot還支持其他一些主要由開發人員或迴歸追蹤人員使用的命令。命令的更多細節請
+參考 `入門指南 <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/getting_started.md>`_
+和 `參考手冊 <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/reference.md>`_ 。
+
+..
+   正文結束
+..
+   如本文件開頭所述,本文以GPL-2.0+或CC-BY-4.0許可發行。如您想僅在CC-BY-4.0許
+   可下重分發本文,請用“Linux內核開發者”作爲作者,並用如下鏈接作爲來源:
+   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/translations/zh_CN/admin-guide/reporting-regressions.rst
+..
+   注意:本RST文件內容只有在來自Linux內核源代碼時是使用CC-BY-4.0許可的,因爲經
+   過處理的版本(如經內核的構建系統)可能包含來自使用更嚴格許可證的文件的內容。
+
diff --git a/Documentation/translations/zh_TW/admin-guide/security-bugs.rst b/Documentation/translations/zh_TW/admin-guide/security-bugs.rst
index 15f8e9005071..c0e9fc247695 100644
--- a/Documentation/translations/zh_TW/admin-guide/security-bugs.rst
+++ b/Documentation/translations/zh_TW/admin-guide/security-bugs.rst
@@ -7,7 +7,7 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 安全缺陷
 =========
@@ -19,17 +19,17 @@ Linux內核開發人員非常重視安全性。因此我們想知道何時發現
 -----
 
 可以通過電子郵件<security@kernel.org>聯繫Linux內核安全團隊。這是一個安全人員
-的私有列表,他們將幫助驗證錯誤報告並開發和發布修復程序。如果您已經有了一個
+的私有列表,他們將幫助驗證錯誤報告並開發和發佈修復程序。如果您已經有了一個
 修復,請將其包含在您的報告中,這樣可以大大加快進程。安全團隊可能會從區域維護
-人員那裡獲得額外的幫助,以理解和修復安全漏洞。
+人員那裏獲得額外的幫助,以理解和修復安全漏洞。
 
 與任何缺陷一樣,提供的信息越多,診斷和修復就越容易。如果您不清楚哪些信息有用,
-請查看「Documentation/translations/zh_TW/admin-guide/reporting-issues.rst」中
+請查看“Documentation/translations/zh_CN/admin-guide/reporting-issues.rst”中
 概述的步驟。任何利用漏洞的攻擊代碼都非常有用,未經報告者同意不會對外發布,除
 非已經公開。
 
-請儘可能發送無附件的純文本電子郵件。如果所有的細節都藏在附件里,那麼就很難對
-一個複雜的問題進行上下文引用的討論。把它想像成一個
+請儘可能發送無附件的純文本電子郵件。如果所有的細節都藏在附件裏,那麼就很難對
+一個複雜的問題進行上下文引用的討論。把它想象成一個
 :doc:`常規的補丁提交 <../process/submitting-patches>` (即使你還沒有補丁):
 描述問題和影響,列出復現步驟,然後給出一個建議的解決方案,所有這些都是純文本的。
 
@@ -38,15 +38,15 @@ Linux內核開發人員非常重視安全性。因此我們想知道何時發現
 
 安全列表不是公開渠道。爲此,請參見下面的協作。
 
-一旦開發出了健壯的補丁,發布過程就開始了。對公開的缺陷的修復會立即發布。
+一旦開發出了健壯的補丁,發佈過程就開始了。對公開的缺陷的修復會立即發佈。
 
-儘管我們傾向於在未公開缺陷的修復可用時即發布補丁,但應報告者或受影響方的請求,
-這可能會被推遲到發布過程開始後的7日內,如果根據缺陷的嚴重性需要更多的時間,
-則可額外延長到14天。推遲發布修復的唯一有效原因是爲了適應QA的邏輯和需要發布
+儘管我們傾向於在未公開缺陷的修復可用時即發佈補丁,但應報告者或受影響方的請求,
+這可能會被推遲到發佈過程開始後的7日內,如果根據缺陷的嚴重性需要更多的時間,
+則可額外延長到14天。推遲發佈修復的唯一有效原因是爲了適應QA的邏輯和需要發佈
 協調的大規模部署。
 
 雖然可能與受信任的個人共享受限信息以開發修復,但未經報告者許可,此類信息不會
-與修復程序一起發布或發布在任何其他披露渠道上。這包括但不限於原始錯誤報告和
+與修復程序一起發佈或發佈在任何其他披露渠道上。這包括但不限於原始錯誤報告和
 後續討論(如有)、漏洞、CVE信息或報告者的身份。
 
 換句話說,我們唯一感興趣的是修復缺陷。提交給安全列表的所有其他資料以及對報告
@@ -57,10 +57,10 @@ Linux內核開發人員非常重視安全性。因此我們想知道何時發現
 
 對敏感缺陷(例如那些可能導致權限提升的缺陷)的修復可能需要與私有郵件列表
 <linux-distros@vs.openwall.org>進行協調,以便分發供應商做好準備,在公開披露
-上游補丁時發布一個已修復的內核。發行版將需要一些時間來測試建議的補丁,通常
-會要求至少幾天的限制,而供應商更新發布更傾向於周二至周四。若合適,安全團隊
+上游補丁時發佈一個已修復的內核。發行版將需要一些時間來測試建議的補丁,通常
+會要求至少幾天的限制,而供應商更新發布更傾向於週二至週四。若合適,安全團隊
 可以協助這種協調,或者報告者可以從一開始就包括linux發行版。在這種情況下,請
-記住在電子郵件主題行前面加上「[vs]」,如linux發行版wiki中所述:
+記住在電子郵件主題行前面加上“[vs]”,如linux發行版wiki中所述:
 <http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists>。
 
 CVE分配
diff --git a/Documentation/translations/zh_TW/admin-guide/sysrq.rst b/Documentation/translations/zh_TW/admin-guide/sysrq.rst
new file mode 100644
index 000000000000..446277674b64
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/sysrq.rst
@@ -0,0 +1,283 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/sysrq.rst
+
+:翻譯:
+
+ 黃軍華 Junhua Huang <huang.junhua@zte.com.cn>
+
+:校譯:
+
+ 司延騰 Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_admin-guide_sysrq:
+
+Linux 魔法系統請求鍵駭客
+========================
+
+針對 sysrq.c 的文檔說明
+
+什麼是魔法 SysRq 鍵?
+~~~~~~~~~~~~~~~~~~~~~
+
+它是一個你可以輸入的具有魔法般的組合鍵。
+無論內核在做什麼,內核都會響應 SysRq 鍵的輸入,除非內核完全卡死。
+
+如何使能魔法 SysRq 鍵?
+~~~~~~~~~~~~~~~~~~~~~~~
+
+在配置內核時,我們需要設置 'Magic SysRq key (CONFIG_MAGIC_SYSRQ)' 爲 'Y'。
+當運行一個編譯進 sysrq 功能的內核時,/proc/sys/kernel/sysrq 控制着被
+SysRq 鍵調用的功能許可。這個文件的默認值由 CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE
+配置符號設定,文件本身默認設置爲 1。以下是 /proc/sys/kernel/sysrq 中可能的
+值列表:
+
+   -  0 - 完全不使能 SysRq 鍵
+   -  1 - 使能 SysRq 鍵的全部功能
+   - >1 - 對於允許的 SysRq 鍵功能的比特掩碼(參見下面更詳細的功能描述)::
+
+          2 =   0x2 - 使能對控制檯日誌記錄級別的控制
+          4 =   0x4 - 使能對鍵盤的控制 (SAK, unraw)
+          8 =   0x8 - 使能對進程的調試導出等
+         16 =  0x10 - 使能同步命令
+         32 =  0x20 - 使能重新掛載只讀
+         64 =  0x40 - 使能對進程的信號操作 (term, kill, oom-kill)
+        128 =  0x80 - 允許重啓、斷電
+        256 = 0x100 - 允許讓所有實時任務變普通任務
+
+你可以通過如下命令把值設置到這個文件中::
+
+    echo "number" >/proc/sys/kernel/sysrq
+
+這裏被寫入的 number 可以是 10 進制數,或者是帶着 0x 前綴的 16 進制數。
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE 必須是以 16 進制數寫入。
+
+注意,``/proc/sys/kernel/sysrq`` 的值隻影響通過鍵盤觸發 SySRq 的調用,對於
+通過 ``/proc/sysrq-trigger`` 的任何操作調用都是允許的
+(通過具有系統權限的用戶)。
+
+如何使用魔法 SysRq 鍵?
+~~~~~~~~~~~~~~~~~~~~~~~
+
+在 x86 架構上
+	你可以按下鍵盤組合鍵 :kbd:`ALT-SysRq-<command key>`。
+
+	.. note::
+	   一些鍵盤可能沒有標識 'SySRq' 鍵。'SySRq' 鍵也被當做 'Print Screen'鍵。
+	   同時有些鍵盤無法處理同時按下這麼多鍵,因此你可以先按下鍵盤 :kbd:`Alt` 鍵,
+	   然後按下鍵盤 :kbd:`SysRq` 鍵,再釋放鍵盤 :kbd:`SysRq` 鍵,之後按下鍵盤上命令鍵
+	   :kbd:`<command key>`,最後釋放所有鍵。
+
+在 SPARC 架構上
+	你可以按下鍵盤組合鍵 :kbd:`ALT-STOP-<command key>` 。
+
+在串行控制檯(只針對 PC 類型的標準串口)
+        你可以發一個 ``BREAK`` ,然後在 5 秒內發送一個命令鍵,
+	發送 ``BREAK`` 兩次將被翻譯爲一個正常的 BREAK 操作。
+
+在 PowerPC 架構上
+	按下鍵盤組合鍵 :kbd:`ALT - Print Screen` (或者 :kbd:`F13`) - :kbd:`<命令鍵>` 。
+        :kbd:`Print Screen` (或者 :kbd:`F13`) - :kbd:`<命令鍵>` 或許也能實現。
+
+在其他架構上
+	如果你知道其他架構的組合鍵,請告訴我,我可以把它們添加到這部分。
+
+在所有架構上
+	寫一個字符到 /proc/sysrq-trigger 文件,例如::
+
+		echo t > /proc/sysrq-trigger
+
+這個命令鍵 :kbd:`<command key>` 是區分大小寫的。
+
+什麼是命令鍵?
+~~~~~~~~~~~~~~
+
+=========== ================================================================
+命令鍵	    功能
+=========== ================================================================
+``b``	    將立即重啓系統,不會同步或者卸載磁盤。
+
+``c``	    將執行系統 crash,如果配置了系統 crashdump,將執行 crashdump。
+
+``d``	    顯示所有持有的鎖。
+
+``e``	    發送 SIGTERM 信號給所有進程,除了 init 進程。
+
+``f``	    將調用 oom killer 殺掉一個過度佔用內存的進程,如果什麼任務都沒殺,
+            也不會 panic。
+
+``g``	    kgdb 使用(內核調試器)。
+
+``h``	    將會顯示幫助。(實際上除了這裏列舉的鍵,其他的都將顯示幫助,
+	    但是 ``h`` 容易記住):-)
+
+``i``	    發送 SIGKILL 給所有進程,除了 init 進程。
+
+``j``	    強制性的 “解凍它” - 用於被 FIFREEZE ioctl 操作凍住的文件系統。
+
+``k``	    安全訪問祕鑰(SAK)殺掉在當前虛擬控制檯的所有程序,注意:參考
+            下面 SAK 節重要論述。
+
+``l``	    顯示所有活動 cpu 的棧回溯。
+
+``m``	    將導出當前內存信息到你的控制檯。
+
+``n``	    用於使所有實時任務變成普通任務。
+
+``o``	    將關閉系統(如果配置和支持的話)。
+
+``p``	    將導出當前寄存器和標誌位到控制檯。
+
+``q``	    將導出每個 cpu 上所有已裝備的高精度定時器(不是完整的
+            time_list 文件顯示的 timers)和所有時鐘事件設備的詳細信息。
+
+``r``	    關閉鍵盤的原始模式,設置爲轉換模式。
+
+``s``	    將嘗試同步所有的已掛載文件系統。
+
+``t``	    將導出當前所有任務列表和它們的信息到控制檯。
+
+``u``	    將嘗試重新掛載已掛載文件系統爲只讀。
+
+``v``	    強制恢復幀緩存控制檯。
+``v``	    觸發 ETM 緩存導出 [ARM 架構特有]
+
+``w``	    導出處於不可中斷狀態(阻塞)的任務。
+
+``x``	    在 ppc/powerpc 架構上用於 xmon 接口。
+            在 sparc64 架構上用於顯示全局的 PMU(性能監控單元)寄存器。
+            在 MIPS 架構上導出所有的 tlb 條目。
+
+``y``	    顯示全局 cpu 寄存器 [SPARC-64 架構特有]
+
+``z``	    導出 ftrace 緩存信息
+
+``0``-``9`` 設置控制檯日誌級別,該級別控制什麼樣的內核信息將被打印到你的
+	    控制檯。(比如 ``0`` ,將使得只有緊急信息,像 PANICs or OOPSes
+	    才能到你的控制檯。)
+=========== ================================================================
+
+好了,我能用他們做什麼呢?
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+嗯,當你的 X 服務端或者 svgalib 程序崩潰,unraw(r) 非原始模式命令鍵是非常
+方便的。
+
+sak(k)(安全訪問祕鑰)在你嘗試登陸的同時,又想確保當前控制檯沒有可以獲取你的
+密碼的特洛伊木馬程序運行時是有用的。它會殺掉給定控制檯的所有程序,這樣你
+就可以確認當前的登陸提示程序是實際來自 init 進程的程序,而不是某些特洛伊
+木馬程序。
+
+.. important::
+
+   在其實際的形式中,在兼容 C2 安全標準的系統上,它不是一個真正的 SAK,
+   它也不應該誤認爲此。
+
+似乎其他人發現其可以作爲(系統終端聯機鍵)當你想退出一個程序,
+同時不會讓你切換控制檯的方法。(比如,X 服務端或者 svgalib 程序)
+
+``reboot(b)`` 是個好方法,當你不能關閉機器時,它等同於按下"復位"按鈕。
+
+``crash(c)`` 可以用於手動觸發一個 crashdump,當系統卡住時。
+注意當 crashdump 機制不可用時,這個只是觸發一個內核 crash。
+
+``sync(s)`` 在拔掉可移動介質之前,或者在使用不提供優雅關機的
+救援 shell 之後很方便 -- 它將確保你的數據被安全地寫入磁盤。注意,在你看到
+屏幕上出現 "OK" 和 "Done" 之前,同步還沒有發生。
+
+``umount(u)`` 可以用來標記文件系統正常卸載,從正在運行的系統角度來看,它們將
+被重新掛載爲只讀。這個重新掛載動作直到你看到 "OK" 和 "Done" 信息出現在屏幕上
+纔算完成。
+
+日誌級別 ``0`` - ``9`` 用於當你的控制檯被大量的內核信息衝擊,你不想看見的時候。
+選擇 ``0`` 將禁止除了最緊急的內核信息外的所有的內核信息輸出到控制檯。(但是如果
+syslogd/klogd 進程是運行的,它們仍將被記錄。)
+
+``term(e)`` 和 ``kill(i)`` 用於當你有些有點失控的進程,你無法通過其他方式殺掉
+它們的時候,特別是它正在創建其他進程。
+
+"just thaw ``it(j)`` " 用於當你的系統由於一個 FIFREEZE ioctl 調用而產生的文件
+系統凍結,而導致的不響應時。
+
+有的時候 SysRq 鍵在使用它之後,看起來像是“卡住”了,我能做些什麼?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+這也會發生在我這,我發現輕敲鍵盤兩側的 shift、alt 和 control 鍵,然後再次敲擊
+一個無效的 SysRq 鍵序列可以解決問題。(比如,像鍵盤組合鍵 :kbd:`alt-sysrq-z` )
+切換到另一個虛擬控制檯(鍵盤操作 :kbd:`ALT+Fn` ),然後再切回來應該也有幫助。
+
+我敲擊了 SysRq 鍵,但像是什麼都沒發生,發生了什麼錯誤?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+有一些鍵盤對於 SysRq 鍵設置了不同的鍵值,而不是提前定義的 99
+(查看在 ``include/uapi/linux/input-event-codes.h`` 文件中 ``KEY_SYSRQ`` 的定義)
+或者就根本沒有 SysRq 鍵。在這些場景下,執行 ``showkey -s`` 命令來找到一個合適
+的掃描碼序列,然後使用 ``setkeycodes <sequence> 99`` 命令映射這個序列值到通用
+的 SysRq 鍵編碼上(比如 ``setkeycodes e05b 99`` )。最好將這個命令放在啓動腳本
+中。
+哦,順便說一句,你十秒鐘不輸入任何東西就將退出 “showkey”。
+
+我想添加一個 SysRq 鍵事件到一個模塊中,如何去做呢?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+爲了註冊一個基礎函數到這個表中,首先你必須包含 ``include/linux/sysrq.h`` 頭
+文件,這個頭文件定義了你所需要的所有東西。然後你必須創建一個 ``sysrq_key_op``
+結構體,然後初始化它,使用如下內容,A) 你將使用的這個鍵的處理函數, B) 一個
+help_msg 字符串,在 SysRq 鍵打印幫助信息時將打印出來,C) 一個 action_msg 字
+符串,就在你的處理函數調用前打印出來。你的處理函數必須符合在 'sysrq.h' 文件中
+的函數原型。
+
+在 ``sysrq_key_op`` 結構體被創建後,你可以調用內核函數
+``register_sysrq_key(int key, const struct sysrq_key_op *op_p);``,
+該函數在表中的 'key' 對應位置內容是空的情況下,將通過 ``op_p`` 指針註冊這個操作
+函數到表中 'key' 對應位置上。在模塊卸載的時候,你必須調用
+``unregister_sysrq_key(int key, const struct sysrq_key_op *op_p)`` 函數,該函數
+只有在當前該鍵對應的處理函數被註冊到了 'key' 對應位置時,纔會移除 'op_p' 指針
+對應的鍵值操作函數。這是爲了防止在你註冊之後,該位置被改寫的情況。
+
+魔法 SysRq 鍵系統的工作原理是將鍵對應操作函數註冊到鍵的操作查找表,
+該表定義在 'drivers/tty/sysrq.c' 文件中。
+該鍵表有許多在編譯時候就註冊進去的操作函數,但是是可變的。
+並且有兩個函數作爲操作該表的接口被導出::
+
+	register_sysrq_key 和 unregister_sysrq_key.
+
+當然,永遠不要在表中留下無效指針,即,當你的模塊存在調用 register_sysrq_key()
+函數,它一定要調用 unregister_sysrq_key() 來清除它使用過的 SysRq 鍵表條目。
+表中的空指針是安全的。:)
+
+如果對於某種原因,在 handle_sysrq 調用的處理函數中,你認爲有必要調用
+handle_sysrq 函數時,你必須意識到當前你處於一個鎖中(你同時也處於一箇中斷處理
+函數中,這意味着不能睡眠)。所以這時你必須使用 ``__handle_sysrq_nolock`` 替代。
+
+當我敲擊一個 SysRq 組合鍵時,只有標題打印出現在控制檯?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SysRq 鍵的輸出和所有其他控制檯輸出一樣,受制於控制檯日誌級別控制。
+這意味着,如果內核以發行版內核中常見的 "quiet" 方式啓動,則輸出可能不會出現在實際
+的控制檯上,即使它會出現在 dmesg 緩存中,也可以通過 dmesg 命令和 ``/proc/kmsg``
+文件的消費訪問到。作爲一個特例,來自 sysrq 命令的標題行將被傳遞給所有控制檯
+使用者,就好像當前日誌級別是最大的一樣。如果只發出標題頭,則幾乎可以肯定內核日誌
+級別太低。如果你需要控制檯上的輸出,那麼你將需要臨時提高控制檯日誌級別,通過使用
+鍵盤組合鍵 :kbd:`alt-sysrq-8` 或者::
+
+    echo 8 > /proc/sysrq-trigger
+
+在觸發了你感興趣的 SysRq 鍵命令後,記得恢復日誌級別到正常情況。
+
+我有很多問題時,可以請教誰?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+請教在內核郵件列表上的人,郵箱:
+	linux-kernel@vger.kernel.org
+
+致謝
+~~~~
+
+- Mydraal <vulpyne@vulpyne.net> 撰寫了該文件
+- Adam Sulmicki <adam@cfar.umd.edu> 進行了更新
+- Jeremy M. Dolan <jmd@turbogeek.org> 在 2001/01/28 10:15:59 進行了更新
+- Crutcher Dunnavant <crutcher+kernel@datastacks.com> 添加鍵註冊部分
+
diff --git a/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst b/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst
index d7b3c4276417..47629f6b05de 100644
--- a/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst
+++ b/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst
@@ -7,29 +7,29 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
-受汙染的內核
+受污染的內核
 -------------
 
-當發生一些在稍後調查問題時可能相關的事件時,內核會將自己標記爲「受汙染
-(tainted)」的。不用太過擔心,大多數情況下運行受汙染的內核沒有問題;這些信息
-主要在有人想調查某個問題時才有意義的,因爲問題的真正原因可能是導致內核受汙染
-的事件。這就是爲什麼來自受汙染內核的缺陷報告常常被開發人員忽略,因此請嘗試用
-未受汙染的內核重現問題。
+當發生一些在稍後調查問題時可能相關的事件時,內核會將自己標記爲“受污染
+(tainted)”的。不用太過擔心,大多數情況下運行受污染的內核沒有問題;這些信息
+主要在有人想調查某個問題時纔有意義的,因爲問題的真正原因可能是導致內核受污染
+的事件。這就是爲什麼來自受污染內核的缺陷報告常常被開發人員忽略,因此請嘗試用
+未受污染的內核重現問題。
 
-請注意,即使在您消除導致汙染的原因(亦即卸載專有內核模塊)之後,內核仍將保持
-汙染狀態,以表示內核仍然不可信。這也是爲什麼內核在注意到內部問題(「kernel
-bug」)、可恢復錯誤(「kernel oops」)或不可恢復錯誤(「kernel panic」)時會列印
-受汙染狀態,並將有關此的調試信息寫入日誌 ``dmesg`` 輸出。也可以通過
-``/proc/`` 中的文件在運行時檢查受汙染的狀態。
+請注意,即使在您消除導致污染的原因(亦即卸載專有內核模塊)之後,內核仍將保持
+污染狀態,以表示內核仍然不可信。這也是爲什麼內核在注意到內部問題(“kernel
+bug”)、可恢復錯誤(“kernel oops”)或不可恢復錯誤(“kernel panic”)時會打印
+受污染狀態,並將有關此的調試信息寫入日誌 ``dmesg`` 輸出。也可以通過
+``/proc/`` 中的文件在運行時檢查受污染的狀態。
 
 
-BUG、Oops或Panics消息中的汙染標誌
+BUG、Oops或Panics消息中的污染標誌
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-在頂部以「CPU:」開頭的一行中可以找到受汙染的狀態;內核是否受到汙染和原因會顯示
-在進程ID(「PID:」)和觸發事件命令的縮寫名稱(「Comm:」)之後::
+在頂部以“CPU:”開頭的一行中可以找到受污染的狀態;內核是否受到污染和原因會顯示
+在進程ID(“PID:”)和觸發事件命令的縮寫名稱(“Comm:”)之後::
 
 	BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
 	Oops: 0002 [#1] SMP PTI
@@ -38,27 +38,27 @@ BUG、Oops或Panics消息中的汙染標誌
 	RIP: 0010:my_oops_init+0x13/0x1000 [kpanic]
 	[...]
 
-如果內核在事件發生時沒有被汙染,您將在那裡看到「Not-tainted:」;如果被汙染,那
-麼它將是「Tainted:」以及字母或空格。在上面的例子中,它看起來是這樣的::
+如果內核在事件發生時沒有被污染,您將在那裏看到“Not-tainted:”;如果被污染,那
+麼它將是“Tainted:”以及字母或空格。在上面的例子中,它看起來是這樣的::
 
 	Tainted: P        W  O
 
 下表解釋了這些字符的含義。在本例中,由於加載了專有模塊( ``P`` ),出現了
 警告( ``W`` ),並且加載了外部構建的模塊( ``O`` ),所以內核早些時候受到
-了汙染。要解碼其他字符,請使用下表。
+了污染。要解碼其他字符,請使用下表。
 
 
-解碼運行時的汙染狀態
+解碼運行時的污染狀態
 ~~~~~~~~~~~~~~~~~~~~~
 
-在運行時,您可以通過讀取 ``cat /proc/sys/kernel/tainted`` 來查詢受汙染狀態。
-如果返回 ``0`` ,則內核沒有受到汙染;任何其他數字都表示受到汙染的原因。解碼
+在運行時,您可以通過讀取 ``cat /proc/sys/kernel/tainted`` 來查詢受污染狀態。
+如果返回 ``0`` ,則內核沒有受到污染;任何其他數字都表示受到污染的原因。解碼
 這個數字的最簡單方法是使用腳本  ``tools/debugging/kernel-chktaint`` ,您的
 發行版可能會將其作爲名爲 ``linux-tools`` 或 ``kernel-tools`` 的包的一部分提
 供;如果沒有,您可以從
 `git.kernel.org <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/tools/debugging/kernel-chktaint>`_
 網站下載此腳本並用 ``sh kernel-chktaint`` 執行,它會在上面引用的日誌中有類似
-語句的機器上列印這樣的內容::
+語句的機器上打印這樣的內容::
 
 	Kernel is Tainted for following reasons:
 	 * Proprietary module was loaded (#0)
@@ -69,19 +69,19 @@ BUG、Oops或Panics消息中的汙染標誌
 	 a more details explanation of the various taint flags.
 	Raw taint value as int/string: 4609/'P        W  O     '
 
-你也可以試著自己解碼這個數字。如果內核被汙染的原因只有一個,那麼這很簡單,
+你也可以試着自己解碼這個數字。如果內核被污染的原因只有一個,那麼這很簡單,
 在本例中您可以通過下表找到數字。如果你需要解碼有多個原因的數字,因爲它是一
-個位域(bitfield),其中每個位表示一個特定類型的汙染的存在或不存在,最好讓
+個位域(bitfield),其中每個位表示一個特定類型的污染的存在或不存在,最好讓
 前面提到的腳本來處理。但是如果您需要快速看一下,可以使用這個shell命令來檢查
 設置了哪些位::
 
 	$ for i in $(seq 18); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done
 
-汙染狀態代碼表
+污染狀態代碼表
 ~~~~~~~~~~~~~~~
 
 ===  =====  ======  ========================================================
- 位  日誌     數字  內核被汙染的原因
+ 位  日誌     數字  內核被污染的原因
 ===  =====  ======  ========================================================
   0   G/P        1  已加載專用模塊
   1   _/F        2  模塊被強制加載
@@ -89,23 +89,23 @@ BUG、Oops或Panics消息中的汙染標誌
   3   _/R        8  模塊被強制卸載
   4   _/M       16  處理器報告了機器檢測異常(MCE)
   5   _/B       32  引用了錯誤的頁或某些意外的頁標誌
-  6   _/U       64  用戶空間應用程式請求的汙染
+  6   _/U       64  用戶空間應用程序請求的污染
   7   _/D      128  內核最近死機了,即曾出現OOPS或BUG
   8   _/A      256  ACPI表被用戶覆蓋
   9   _/W      512  內核發出警告
  10   _/C     1024  已加載staging驅動程序
- 11   _/I     2048  已應用平台固件缺陷的解決方案
- 12   _/O     4096  已加載外部構建(「樹外」)模塊
+ 11   _/I     2048  已應用平臺固件缺陷的解決方案
+ 12   _/O     4096  已加載外部構建(“樹外”)模塊
  13   _/E     8192  已加載未簽名的模塊
  14   _/L    16384  發生軟鎖定
  15   _/K    32768  內核已實時打補丁
- 16   _/X    65536  備用汙染,爲發行版定義並使用
+ 16   _/X    65536  備用污染,爲發行版定義並使用
  17   _/T   131072  內核是用結構隨機化插件構建的
 ===  =====  ======  ========================================================
 
-註:字符 ``_`` 表示空白,以便於閱讀表。
+注:字符 ``_`` 表示空白,以便於閱讀表。
 
-汙染的更詳細解釋
+污染的更詳細解釋
 ~~~~~~~~~~~~~~~~~
 
  0)  ``G`` 加載的所有模塊都有GPL或兼容許可證, ``P`` 加載了任何專有模塊。
@@ -115,14 +115,14 @@ BUG、Oops或Panics消息中的汙染標誌
 
  1)  ``F`` 任何模塊被 ``insmod -f`` 強制加載, ``' '`` 所有模塊正常加載。
 
- 2)  ``S`` 內核運行在不合規範的處理器或系統上:硬體已運行在不受支持的配置中,
-     因此無法保證正確執行。內核將被汙染,例如:
+ 2)  ``S`` 內核運行在不合規範的處理器或系統上:硬件已運行在不受支持的配置中,
+     因此無法保證正確執行。內核將被污染,例如:
 
      - 在x86上:PAE是通過intel CPU(如Pentium M)上的forcepae強制執行的,這些
        CPU不報告PAE,但可能有功能實現,SMP內核在非官方支持的SMP Athlon CPU上
        運行,MSR被暴露到用戶空間中。
      - 在arm上:在某些CPU(如Keystone 2)上運行的內核,沒有啓用某些內核特性。
-     - 在arm64上:CPU之間存在不匹配的硬體特性,引導加載程序以不同的模式引導CPU。
+     - 在arm64上:CPU之間存在不匹配的硬件特性,引導加載程序以不同的模式引導CPU。
      - 某些驅動程序正在被用在不受支持的體系結構上(例如x86_64以外的其他系統
        上的scsi/snic,非x86/x86_64/itanium上的scsi/ips,已經損壞了arm64上
        irqchip/irq-gic的固件設置…)。
@@ -131,22 +131,22 @@ BUG、Oops或Panics消息中的汙染標誌
 
  4)  ``M`` 任何處理器報告了機器檢測異常, ``' '`` 未發生機器檢測異常。
 
- 5)  ``B`` 頁面釋放函數發現錯誤的頁面引用或某些意外的頁面標誌。這表示硬體問題
-     或內核錯誤;日誌中應該有其他信息指示發生此汙染的原因。
+ 5)  ``B`` 頁面釋放函數發現錯誤的頁面引用或某些意外的頁面標誌。這表示硬件問題
+     或內核錯誤;日誌中應該有其他信息指示發生此污染的原因。
 
- 6)  ``U`` 用戶或用戶應用程式特意請求設置受汙染標誌,否則應爲 ``' '`` 。
+ 6)  ``U`` 用戶或用戶應用程序特意請求設置受污染標誌,否則應爲 ``' '`` 。
 
  7)  ``D`` 內核最近死機了,即出現了OOPS或BUG。
 
  8)  ``A`` ACPI表被重寫。
 
- 9)  ``W`` 內核之前已發出過警告(儘管有些警告可能會設置更具體的汙染標誌)。
+ 9)  ``W`` 內核之前已發出過警告(儘管有些警告可能會設置更具體的污染標誌)。
 
  10) ``C`` 已加載staging驅動程序。
 
- 11) ``I`` 內核正在處理平台固件(BIOS或類似軟體)中的嚴重錯誤。
+ 11) ``I`` 內核正在處理平臺固件(BIOS或類似軟件)中的嚴重錯誤。
 
- 12) ``O`` 已加載外部構建(「樹外」)模塊。
+ 12) ``O`` 已加載外部構建(“樹外”)模塊。
 
  13) ``E`` 在支持模塊簽名的內核中加載了未簽名的模塊。
 
@@ -154,8 +154,8 @@ BUG、Oops或Panics消息中的汙染標誌
 
  15) ``K`` 內核已經實時打了補丁。
 
- 16) ``X`` 備用汙染,由Linux發行版定義和使用。
+ 16) ``X`` 備用污染,由Linux發行版定義和使用。
 
  17) ``T`` 內核構建時使用了randstruct插件,它可以有意生成非常不尋常的內核結構
-     布局(甚至是性能病態的布局),這在調試時非常有用。於構建時設置。
+     佈局(甚至是性能病態的佈局),這在調試時非常有用。於構建時設置。
 
diff --git a/Documentation/translations/zh_TW/admin-guide/unicode.rst b/Documentation/translations/zh_TW/admin-guide/unicode.rst
index 720875be5ef8..a2b48b5d0a64 100644
--- a/Documentation/translations/zh_TW/admin-guide/unicode.rst
+++ b/Documentation/translations/zh_TW/admin-guide/unicode.rst
@@ -7,7 +7,7 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 Unicode(統一碼)支持
 ======================
@@ -37,15 +37,15 @@ IBMPC_MAP       IBM code page 437               ESC ( U
 USER_MAP        User defined                    ESC ( K
 =============== =============================== ================
 
-特別是 ESC ( U 不再是「直通字體」,因爲字體可能與IBM字符集完全不同。
+特別是 ESC ( U 不再是“直通字體”,因爲字體可能與IBM字符集完全不同。
 例如,即使加載了一個Latin-1字體,也允許使用塊圖形(block graphics)。
 
 請注意,儘管這些代碼與ISO 2022類似,但這些代碼及其用途都與ISO 2022不匹配;
 Linux有兩個八位代碼(G0和G1),而ISO 2022有四個七位代碼(G0-G3)。
 
-根據Unicode標準/ISO 10646,U+F000到U+F8FF被保留用於作業系統範圍內的分配
-(Unicode標準將其稱爲「團體區域(Corporate Zone)」,因爲這對於Linux是不準確
-的,所以我們稱之爲「Linux區域」)。選擇U+F000作爲起點,因爲它允許直接映射
+根據Unicode標準/ISO 10646,U+F000到U+F8FF被保留用於操作系統範圍內的分配
+(Unicode標準將其稱爲“團體區域(Corporate Zone)”,因爲這對於Linux是不準確
+的,所以我們稱之爲“Linux區域”)。選擇U+F000作爲起點,因爲它允許直接映射
 區域以2的大倍數開始(以防需要1024或2048個字符的字體)。這就留下U+E000到
 U+EFFF作爲最終用戶區。
 
@@ -87,7 +87,7 @@ U+F813 KEYBOARD SYMBOL SOLID APPLE
 克林貢(Klingon)語支持
 ------------------------
 
-1996年,Linux是世界上第一個添加對人工語言克林貢支持的作業系統,克林貢是由
+1996年,Linux是世界上第一個添加對人工語言克林貢支持的操作系統,克林貢是由
 Marc Okrand爲《星際迷航》電視連續劇創造的。這種編碼後來被徵募Unicode註冊表
 (ConScript Unicode Registry,CSUR)採用,並建議(但最終被拒絕)納入Unicode
 平面一。不過,它仍然是Linux區域中的Linux/CSUR私有分配。
-- 
2.34.1


^ permalink raw reply related	[relevance 4%]

* [PATCH 1/6] docs/zh_TW: update admin-guide
@ 2023-07-16  9:46  4% Hu Haowen
  0 siblings, 0 replies; 200+ results
From: Hu Haowen @ 2023-07-16  9:46 UTC (permalink / raw)
  To: corbet; +Cc: Hu Haowen, linux-doc, linux-kernel

Update zh_TW's admin-guide documentation concentrating on the following
aspects:

    * The file tree structure changes of the main documentation;
    * Some changes and ideas from zh_CN translation;
    * Removal for several obsoleted contents within the zh_TW translation
      or those which are not exising anymore in the main documentation.
    * Replacements for some incorrect words and phrases in traditional
      Chinese or those which are odd within their context being hard for
      readers to comprehend.

Signed-off-by: Hu Haowen <src.res.211@gmail.com>
---
 .../translations/zh_TW/admin-guide/README.rst | 166 ++--
 .../zh_TW/admin-guide/bootconfig.rst          | 294 +++++++
 .../zh_TW/admin-guide/bug-bisect.rst          |  12 +-
 .../zh_TW/admin-guide/bug-hunting.rst         |  40 +-
 .../zh_TW/admin-guide/clearing-warn-once.rst  |   6 +-
 .../zh_TW/admin-guide/cpu-load.rst            |  10 +-
 .../zh_TW/admin-guide/cputopology.rst         |  98 +++
 .../translations/zh_TW/admin-guide/index.rst  | 136 ++--
 .../translations/zh_TW/admin-guide/init.rst   |  38 +-
 .../zh_TW/admin-guide/lockup-watchdogs.rst    |  69 ++
 .../zh_TW/admin-guide/mm/damon/index.rst      |  31 +
 .../zh_TW/admin-guide/mm/damon/lru_sort.rst   | 265 +++++++
 .../zh_TW/admin-guide/mm/damon/reclaim.rst    | 230 ++++++
 .../zh_TW/admin-guide/mm/damon/start.rst      | 126 +++
 .../zh_TW/admin-guide/mm/damon/usage.rst      | 593 ++++++++++++++
 .../zh_TW/admin-guide/mm/index.rst            |  52 ++
 .../translations/zh_TW/admin-guide/mm/ksm.rst | 201 +++++
 .../zh_TW/admin-guide/reporting-issues.rst    | 729 +++++++++---------
 .../admin-guide/reporting-regressions.rst     | 371 +++++++++
 .../zh_TW/admin-guide/security-bugs.rst       |  28 +-
 .../translations/zh_TW/admin-guide/sysrq.rst  | 283 +++++++
 .../zh_TW/admin-guide/tainted-kernels.rst     |  86 +--
 .../zh_TW/admin-guide/unicode.rst             |  12 +-
 23 files changed, 3233 insertions(+), 643 deletions(-)
 create mode 100644 Documentation/translations/zh_TW/admin-guide/bootconfig.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/cputopology.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/index.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/mm/ksm.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst
 create mode 100644 Documentation/translations/zh_TW/admin-guide/sysrq.rst

diff --git a/Documentation/translations/zh_TW/admin-guide/README.rst b/Documentation/translations/zh_TW/admin-guide/README.rst
index 6ce97edbab37..4cb581f5994a 100644
--- a/Documentation/translations/zh_TW/admin-guide/README.rst
+++ b/Documentation/translations/zh_TW/admin-guide/README.rst
@@ -7,18 +7,18 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
-Linux內核5.x版本 <http://kernel.org/>
+Linux內核6.x版本 <http://kernel.org/>
 =========================================
 
-以下是Linux版本5的發行註記。仔細閱讀它們,
+以下是Linux版本6的發行註記。仔細閱讀它們,
 它們會告訴你這些都是什麼,解釋如何安裝內核,以及遇到問題時該如何做。
 
 什麼是Linux?
 ---------------
 
-  Linux是Unix作業系統的克隆版本,由Linus Torvalds在一個鬆散的網絡黑客
+  Linux是Unix操作系統的克隆版本,由Linus Torvalds在一個鬆散的網絡黑客
   (Hacker,無貶義)團隊的幫助下從頭開始編寫。它旨在實現兼容POSIX和
   單一UNIX規範。
 
@@ -28,7 +28,7 @@ Linux內核5.x版本 <http://kernel.org/>
 
   Linux在GNU通用公共許可證,版本2(GNU GPLv2)下分發,詳見隨附的COPYING文件。
 
-它能在什麼樣的硬體上運行?
+它能在什麼樣的硬件上運行?
 -----------------------------
 
   雖然Linux最初是爲32位的x86 PC機(386或更高版本)開發的,但今天它也能運行在
@@ -40,16 +40,16 @@ Linux內核5.x版本 <http://kernel.org/>
   單元(PMMU)和一個移植的GNU C編譯器(gcc;GNU Compiler Collection,GCC的一
   部分)。Linux也被移植到許多沒有PMMU的體系架構中,儘管功能顯然受到了一定的
   限制。
-  Linux也被移植到了其自己上。現在可以將內核作爲用戶空間應用程式運行——這被
+  Linux也被移植到了其自己上。現在可以將內核作爲用戶空間應用程序運行——這被
   稱爲用戶模式Linux(UML)。
 
 文檔
 -----
-網際網路上和書籍上都有大量的電子文檔,既有Linux專屬文檔,也有與一般UNIX問題相關
+因特網上和書籍上都有大量的電子文檔,既有Linux專屬文檔,也有與一般UNIX問題相關
 的文檔。我建議在任何Linux FTP站點上查找LDP(Linux文檔項目)書籍的文檔子目錄。
 本自述文件並不是關於系統的文檔:有更好的可用資源。
 
- - 網際網路上和書籍上都有大量的(電子)文檔,既有Linux專屬文檔,也有與普通
+ - 因特網上和書籍上都有大量的(電子)文檔,既有Linux專屬文檔,也有與普通
    UNIX問題相關的文檔。我建議在任何有LDP(Linux文檔項目)書籍的Linux FTP
    站點上查找文檔子目錄。本自述文件並不是關於系統的文檔:有更好的可用資源。
 
@@ -58,33 +58,33 @@ Linux內核5.x版本 <http://kernel.org/>
    :ref:`Documentation/process/changes.rst <changes>` 文件,它包含了升級內核
    可能會導致的問題的相關信息。
 
-安裝內核原始碼
+安裝內核源代碼
 ---------------
 
- - 如果您要安裝完整的原始碼,請把內核tar檔案包放在您有權限的目錄中(例如您
+ - 如果您要安裝完整的源代碼,請把內核tar檔案包放在您有權限的目錄中(例如您
    的主目錄)並將其解包::
 
-     xz -cd linux-5.x.tar.xz | tar xvf -
+     xz -cd linux-6.x.tar.xz | tar xvf -
 
-   將「X」替換成最新內核的版本號。
+   將“X”替換成最新內核的版本號。
 
-   【不要】使用 /usr/src/linux 目錄!這裡有一組庫頭文件使用的內核頭文件
+   【不要】使用 /usr/src/linux 目錄!這裏有一組庫頭文件使用的內核頭文件
    (通常是不完整的)。它們應該與庫匹配,而不是被內核的變化搞得一團糟。
 
- - 您還可以通過打補丁在5.x版本之間升級。補丁以xz格式分發。要通過打補丁進行
-   安裝,請獲取所有較新的補丁文件,進入內核原始碼(linux-5.x)的目錄並
+ - 您還可以通過打補丁在6.x版本之間升級。補丁以xz格式分發。要通過打補丁進行
+   安裝,請獲取所有較新的補丁文件,進入內核源代碼(linux-6.x)的目錄並
    執行::
 
-     xz -cd ../patch-5.x.xz | patch -p1
+     xz -cd ../patch-6.x.xz | patch -p1
 
-   請【按順序】替換所有大於當前原始碼樹版本的「x」,這樣就可以了。您可能想要
+   請【按順序】替換所有大於當前源代碼樹版本的“x”,這樣就可以了。您可能想要
    刪除備份文件(文件名類似xxx~ 或 xxx.orig),並確保沒有失敗的補丁(文件名
    類似xxx# 或 xxx.rej)。如果有,不是你就是我犯了錯誤。
 
-   與5.x內核的補丁不同,5.x.y內核(也稱爲穩定版內核)的補丁不是增量的,而是
-   直接應用於基本的5.x內核。例如,如果您的基本內核是5.0,並且希望應用5.0.3
-   補丁,則不應先應用5.0.1和5.0.2的補丁。類似地,如果您運行的是5.0.2內核,
-   並且希望跳轉到5.0.3,那麼在應用5.0.3補丁之前,必須首先撤銷5.0.2補丁
+   與6.x內核的補丁不同,6.x.y內核(也稱爲穩定版內核)的補丁不是增量的,而是
+   直接應用於基本的6.x內核。例如,如果您的基本內核是6.0,並且希望應用6.0.3
+   補丁,則不應先應用6.0.1和6.0.2的補丁。類似地,如果您運行的是6.0.2內核,
+   並且希望跳轉到6.0.3,那麼在應用6.0.3補丁之前,必須首先撤銷6.0.2補丁
    (即patch -R)。更多關於這方面的內容,請閱讀
    :ref:`Documentation/process/applying-patches.rst <applying_patches>` 。
 
@@ -93,7 +93,7 @@ Linux內核5.x版本 <http://kernel.org/>
 
      linux/scripts/patch-kernel linux
 
-   上面命令中的第一個參數是內核原始碼的位置。補丁是在當前目錄應用的,但是
+   上面命令中的第一個參數是內核源代碼的位置。補丁是在當前目錄應用的,但是
    可以將另一個目錄指定爲第二個參數。
 
  - 確保沒有過時的 .o 文件和依賴項::
@@ -101,30 +101,30 @@ Linux內核5.x版本 <http://kernel.org/>
      cd linux
      make mrproper
 
-   現在您應該已經正確安裝了原始碼。
+   現在您應該已經正確安裝了源代碼。
 
-軟體要求
+軟件要求
 ---------
 
-   編譯和運行5.x內核需要各種軟體包的最新版本。請參考
+   編譯和運行6.x內核需要各種軟件包的最新版本。請參考
    :ref:`Documentation/process/changes.rst <changes>`
-   來了解最低版本要求以及如何升級軟體包。請注意,使用過舊版本的這些包可能會
+   來了解最低版本要求以及如何升級軟件包。請注意,使用過舊版本的這些包可能會
    導致很難追蹤的間接錯誤,因此不要以爲在生成或操作過程中出現明顯問題時可以
    只更新包。
 
 爲內核建立目錄
 ---------------
 
-   編譯內核時,默認情況下所有輸出文件都將與內核原始碼放在一起。使用
+   編譯內核時,默認情況下所有輸出文件都將與內核源代碼放在一起。使用
    ``make O=output/dir`` 選項可以爲輸出文件(包括 .config)指定備用位置。
    例如::
 
-     kernel source code: /usr/src/linux-5.x
+     kernel source code: /usr/src/linux-6.x
      build directory:    /home/name/build/kernel
 
    要配置和構建內核,請使用::
 
-     cd /usr/src/linux-5.x
+     cd /usr/src/linux-6.x
      make O=/home/name/build/kernel menuconfig
      make O=/home/name/build/kernel
      sudo make O=/home/name/build/kernel modules_install install
@@ -136,7 +136,7 @@ Linux內核5.x版本 <http://kernel.org/>
 
    即使只升級一個小版本,也不要跳過此步驟。每個版本中都會添加新的配置選項,
    如果配置文件沒有按預定設置,就會出現奇怪的問題。如果您想以最少的工作量
-   將現有配置升級到新版本,請使用 ``makeoldconfig`` ,它只會詢問您新配置
+   將現有配置升級到新版本,請使用 ``make oldconfig`` ,它只會詢問您新配置
    選項的答案。
 
  - 其他配置命令包括::
@@ -164,17 +164,17 @@ Linux內核5.x版本 <http://kernel.org/>
      "make ${PLATFORM}_defconfig"
                         使用arch/$arch/configs/${PLATFORM}_defconfig中
                         的默認選項值創建一個./.config文件。
-                        用「makehelp」來獲取您體系架構中所有可用平台的列表。
+                        用“make help”來獲取您體系架構中所有可用平臺的列表。
 
      "make allyesconfig"
-                        通過儘可能將選項值設置爲「y」,創建一個
+                        通過儘可能將選項值設置爲“y”,創建一個
                         ./.config文件。
 
      "make allmodconfig"
-                        通過儘可能將選項值設置爲「m」,創建一個
+                        通過儘可能將選項值設置爲“m”,創建一個
                         ./.config文件。
 
-     "make allnoconfig" 通過儘可能將選項值設置爲「n」,創建一個
+     "make allnoconfig" 通過儘可能將選項值設置爲“n”,創建一個
                         ./.config文件。
 
      "make randconfig"  通過隨機設置選項值來創建./.config文件。
@@ -182,7 +182,7 @@ Linux內核5.x版本 <http://kernel.org/>
      "make localmodconfig" 基於當前配置和加載的模塊(lsmod)創建配置。禁用
                            已加載的模塊不需要的任何模塊選項。
 
-                           要爲另一台計算機創建localmodconfig,請將該計算機
+                           要爲另一臺計算機創建localmodconfig,請將該計算機
                            的lsmod存儲到一個文件中,並將其作爲lsmod參數傳入。
 
                            此外,通過在參數LMC_KEEP中指定模塊的路徑,可以將
@@ -200,9 +200,10 @@ Linux內核5.x版本 <http://kernel.org/>
      "make localyesconfig" 與localmodconfig類似,只是它會將所有模塊選項轉換
                            爲內置(=y)。你可以同時通過LMC_KEEP保留模塊。
 
-     "make kvmconfig"   爲kvm客體內核支持啓用其他選項。
+     "make kvm_guest.config"
+                        爲kvm客戶機內核支持啓用其他選項。
 
-     "make xenconfig"   爲xen dom0客體內核支持啓用其他選項。
+     "make xen.config"  爲xen dom0客戶機內核支持啓用其他選項。
 
      "make tinyconfig"  配置儘可能小的內核。
 
@@ -218,10 +219,10 @@ Linux內核5.x版本 <http://kernel.org/>
       這種情況下,數學仿真永遠不會被使用。內核會稍微大一點,但不管
       是否有數學協處理器,都可以在不同的機器上工作。
 
-    - 「kernel hacking」配置細節通常會導致更大或更慢的內核(或兩者
+    - “kernel hacking”配置細節通常會導致更大或更慢的內核(或兩者
       兼而有之),甚至可以通過配置一些例程來主動嘗試破壞壞代碼以發現
       內核問題,從而降低內核的穩定性(kmalloc())。因此,您可能應該
-      用於研究「開發」、「實驗」或「調試」特性相關問題。
+      用於研究“開發”、“實驗”或“調試”特性相關問題。
 
 編譯內核
 ---------
@@ -229,10 +230,8 @@ Linux內核5.x版本 <http://kernel.org/>
  - 確保您至少有gcc 5.1可用。
    有關更多信息,請參閱 :ref:`Documentation/process/changes.rst <changes>` 。
 
-   請注意,您仍然可以使用此內核運行a.out用戶程序。
-
  - 執行 ``make`` 來創建壓縮內核映像。如果您安裝了lilo以適配內核makefile,
-   那麼也可以進行 ``makeinstall`` ,但是您可能需要先檢查特定的lilo設置。
+   那麼也可以進行 ``make install`` ,但是您可能需要先檢查特定的lilo設置。
 
    實際安裝必須以root身份執行,但任何正常構建都不需要。
    無須徒然使用root身份。
@@ -242,8 +241,8 @@ Linux內核5.x版本 <http://kernel.org/>
  - 詳細的內核編譯/生成輸出:
 
    通常,內核構建系統在相當安靜的模式下運行(但不是完全安靜)。但是有時您或
-   其他內核開發人員需要看到編譯、連結或其他命令的執行過程。爲此,可使用
-   「verbose(詳細)」構建模式。
+   其他內核開發人員需要看到編譯、鏈接或其他命令的執行過程。爲此,可使用
+   “verbose(詳細)”構建模式。
    向 ``make`` 命令傳遞 ``V=1`` 來實現,例如::
 
      make V=1 all
@@ -255,15 +254,15 @@ Linux內核5.x版本 <http://kernel.org/>
    與工作內核版本號相同的新內核,請在進行 ``make modules_install`` 安裝
    之前備份modules目錄。
 
-   或者,在編譯之前,使用內核配置選項「LOCALVERSION」向常規內核版本附加
-   一個唯一的後綴。LOCALVERSION可以在「General Setup」菜單中設置。
+   或者,在編譯之前,使用內核配置選項“LOCALVERSION”向常規內核版本附加
+   一個唯一的後綴。LOCALVERSION可以在“General Setup”菜單中設置。
 
  - 爲了引導新內核,您需要將內核映像(例如編譯後的
    .../linux/arch/x86/boot/bzImage)複製到常規可引導內核的位置。
 
  - 不再支持在沒有LILO等啓動裝載程序幫助的情況下直接從軟盤引導內核。
 
-   如果從硬碟引導Linux,很可能使用LILO,它使用/etc/lilo.conf文件中
+   如果從硬盤引導Linux,很可能使用LILO,它使用/etc/lilo.conf文件中
    指定的內核映像文件。內核映像文件通常是/vmlinuz、/boot/vmlinuz、
    /bzImage或/boot/bzImage。使用新內核前,請保存舊映像的副本,並複製
    新映像覆蓋舊映像。然後您【必須重新運行LILO】來更新加載映射!否則,
@@ -284,68 +283,13 @@ Linux內核5.x版本 <http://kernel.org/>
 若遇到問題
 -----------
 
- - 如果您發現了一些可能由於內核缺陷所導致的問題,請檢查MAINTAINERS(維護者)
-   文件看看是否有人與令您遇到麻煩的內核部分相關。如果無人在此列出,那麼第二
-   個最好的方案就是把它們發給我(torvalds@linux-foundation.org),也可能發送
-   到任何其他相關的郵件列表或新聞組。
-
- - 在所有的缺陷報告中,【請】告訴我們您在說什麼內核,如何復現問題,以及您的
-   設置是什麼的(使用您的常識)。如果問題是新的,請告訴我;如果問題是舊的,
-   請嘗試告訴我您什麼時候首次注意到它。
-
- - 如果缺陷導致如下消息::
-
-     unable to handle kernel paging request at address C0000010
-     Oops: 0002
-     EIP:   0010:XXXXXXXX
-     eax: xxxxxxxx   ebx: xxxxxxxx   ecx: xxxxxxxx   edx: xxxxxxxx
-     esi: xxxxxxxx   edi: xxxxxxxx   ebp: xxxxxxxx
-     ds: xxxx  es: xxxx  fs: xxxx  gs: xxxx
-     Pid: xx, process nr: xx
-     xx xx xx xx xx xx xx xx xx xx
-
-   或者類似的內核調試信息顯示在屏幕上或在系統日誌里,請【如實】複製它。
-   可能對你來說轉儲(dump)看起來不可理解,但它確實包含可能有助於調試問題的
-   信息。轉儲上方的文本也很重要:它說明了內核轉儲代碼的原因(在上面的示例中,
-   是由於內核指針錯誤)。更多關於如何理解轉儲的信息,請參見
-   Documentation/admin-guide/bug-hunting.rst。
-
- - 如果使用 CONFIG_KALLSYMS 編譯內核,則可以按原樣發送轉儲,否則必須使用
-   ``ksymoops`` 程序來理解轉儲(但通常首選使用CONFIG_KALLSYMS編譯)。
-   此實用程序可從
-   https://www.kernel.org/pub/linux/utils/kernel/ksymoops/ 下載。
-   或者,您可以手動執行轉儲查找:
-
- - 在調試像上面這樣的轉儲時,如果您可以查找EIP值的含義,這將非常有幫助。
-   十六進位值本身對我或其他任何人都沒有太大幫助:它會取決於特定的內核設置。
-   您應該做的是從EIP行獲取十六進位值(忽略 ``0010:`` ),然後在內核名字列表
-   中查找它,以查看哪個內核函數包含有問題的地址。
-
-   要找到內核函數名,您需要找到與顯示症狀的內核相關聯的系統二進位文件。就是
-   文件「linux/vmlinux」。要提取名字列表並將其與內核崩潰中的EIP進行匹配,
-   請執行::
-
-     nm vmlinux | sort | less
-
-   這將爲您提供一個按升序排序的內核地址列表,從中很容易找到包含有問題的地址
-   的函數。請注意,內核調試消息提供的地址不一定與函數地址完全匹配(事實上,
-   這是不可能的),因此您不能只「grep」列表:不過列表將爲您提供每個內核函數
-   的起點,因此通過查找起始地址低於你正在搜索的地址,但後一個函數的高於的
-   函數,你會找到您想要的。實際上,在您的問題報告中加入一些「上下文」可能是
-   一個好主意,給出相關的上下幾行。
-
-   如果您由於某些原因無法完成上述操作(如您使用預編譯的內核映像或類似的映像),
-   請儘可能多地告訴我您的相關設置信息,這會有所幫助。有關詳細信息請閱讀
-   『Documentation/admin-guide/reporting-issues.rst』。
-
- - 或者,您可以在正在運行的內核上使用gdb(只讀的;即不能更改值或設置斷點)。
-   爲此,請首先使用-g編譯內核;適當地編輯arch/x86/Makefile,然後執行 ``make
-   clean`` 。您還需要啓用CONFIG_PROC_FS(通過 ``make config`` )。
-
-   使用新內核重新啓動後,執行 ``gdb vmlinux /proc/kcore`` 。現在可以使用所有
-   普通的gdb命令。查找系統崩潰點的命令是 ``l *0xXXXXXXXX`` (將xxx替換爲EIP
-   值)。
-
-   用gdb無法調試一個當前未運行的內核是由於gdb(錯誤地)忽略了編譯內核的起始
-   偏移量。
+如果您發現了一些可能由於內核缺陷所導致的問題,請參閱:
+Documentation/translations/zh_CN/admin-guide/reporting-issues.rst 。
+
+想要理解內核錯誤報告,請參閱:
+Documentation/translations/zh_CN/admin-guide/bug-hunting.rst 。
+
+更多用GDB調試內核的信息,請參閱:
+Documentation/translations/zh_CN/dev-tools/gdb-kernel-debugging.rst
+和 Documentation/dev-tools/kgdb.rst 。
 
diff --git a/Documentation/translations/zh_TW/admin-guide/bootconfig.rst b/Documentation/translations/zh_TW/admin-guide/bootconfig.rst
new file mode 100644
index 000000000000..abac5aa60f67
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/bootconfig.rst
@@ -0,0 +1,294 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/bootconfig.rst
+
+:譯者: 吳想成 Wu XiangCheng <bobwxc@email.cn>
+
+========
+引導配置
+========
+
+:作者: Masami Hiramatsu <mhiramat@kernel.org>
+
+概述
+====
+
+引導配置擴展了現有的內核命令行,以一種更有效率的方式在引導內核時進一步支持
+鍵值數據。這允許管理員傳遞一份結構化關鍵字的配置文件。
+
+配置文件語法
+============
+
+引導配置文件的語法採用非常簡單的鍵值結構。每個關鍵字由點連接的單詞組成,鍵
+和值由 ``=`` 連接。值以分號( ``;`` )或換行符( ``\n`` )結尾。數組值中每
+個元素由逗號( ``,`` )分隔。::
+
+  KEY[.WORD[...]] = VALUE[, VALUE2[...]][;]
+
+與內核命令行語法不同,逗號和 ``=`` 周圍允許有空格。
+
+關鍵字只允許包含字母、數字、連字符( ``-`` )和下劃線( ``_`` )。值可包含
+可打印字符和空格,但分號( ``;`` )、換行符( ``\n`` )、逗號( ``,`` )、
+井號( ``#`` )和右大括號( ``}`` )等分隔符除外。
+
+如果你需要在值中使用這些分隔符,可以用雙引號( ``"VALUE"`` )或單引號
+( ``'VALUE'`` )括起來。注意,引號無法轉義。
+
+鍵的值可以爲空或不存在。這些鍵用於檢查該鍵是否存在(類似布爾值)。
+
+鍵值語法
+--------
+
+引導配置文件語法允許用戶通過大括號合併鍵名部分相同的關鍵字。例如::
+
+ foo.bar.baz = value1
+ foo.bar.qux.quux = value2
+
+也可以寫成::
+
+ foo.bar {
+    baz = value1
+    qux.quux = value2
+ }
+
+或者更緊湊一些,寫成::
+
+ foo.bar { baz = value1; qux.quux = value2 }
+
+在這兩種樣式中,引導解析時相同的關鍵字都會自動合併。因此可以追加類似的樹或
+鍵值。
+
+相同關鍵字的值
+--------------
+
+禁止兩個或多個值或數組共享同一個關鍵字。例如::
+
+ foo = bar, baz
+ foo = qux  # !錯誤! 我們不可以重定義相同的關鍵字
+
+如果你想要更新值,必須顯式使用覆蓋操作符 ``:=`` 。例如::
+
+ foo = bar, baz
+ foo := qux
+
+這樣 ``foo`` 關鍵字的值就變成了 ``qux`` 。這對於通過添加(部分)自定義引導
+配置來覆蓋默認值非常有用,免於解析默認引導配置。
+
+如果你想對現有關鍵字追加值作爲數組成員,可以使用 ``+=`` 操作符。例如::
+
+ foo = bar, baz
+ foo += qux
+
+這樣, ``foo`` 關鍵字就同時擁有了 ``bar`` , ``baz`` 和 ``qux`` 。
+
+此外,父關鍵字下可同時存在值和子關鍵字。
+例如,下列配置是可行的。::
+
+ foo = value1
+ foo.bar = value2
+ foo := value3 # 這會更新foo的值。
+
+注意,裸值不能直接放進結構化關鍵字中,必須在大括號外定義它。例如::
+
+ foo {
+     bar = value1
+     bar {
+         baz = value2
+         qux = value3
+     }
+ }
+
+同時,關鍵字下值節點的順序是固定的。如果值和子關鍵字同時存在,值永遠是該關
+鍵字的第一個子節點。因此如果用戶先指定子關鍵字,如::
+
+ foo.bar = value1
+ foo = value2
+
+則在程序(和/proc/bootconfig)中,它會按如下顯示::
+
+ foo = value2
+ foo.bar = value1
+
+註釋
+----
+
+配置語法接受shell腳本風格的註釋。註釋以井號( ``#`` )開始,到換行符
+( ``\n`` )結束。
+
+::
+
+ # comment line
+ foo = value # value is set to foo.
+ bar = 1, # 1st element
+       2, # 2nd element
+       3  # 3rd element
+
+會被解析爲::
+
+ foo = value
+ bar = 1, 2, 3
+
+注意你不能把註釋放在值和分隔符( ``,`` 或 ``;`` )之間。如下配置語法是錯誤的::
+
+ key = 1 # comment
+       ,2
+
+
+/proc/bootconfig
+================
+
+/proc/bootconfig是引導配置的用戶空間接口。與/proc/cmdline不同,此文件內容以
+鍵值列表樣式顯示。
+每個鍵值對一行,樣式如下::
+
+ KEY[.WORDS...] = "[VALUE]"[,"VALUE2"...]
+
+
+用引導配置引導內核
+==================
+
+用引導配置引導內核有兩種方法:將引導配置附加到initrd鏡像或直接嵌入內核中。
+
+*initrd: initial RAM disk,初始內存磁盤*
+
+將引導配置附加到initrd
+----------------------
+
+由於默認情況下引導配置文件是用initrd加載的,因此它將被添加到initrd(initramfs)
+鏡像文件的末尾,其中包含填充、大小、校驗值和12字節幻數,如下所示::
+
+ [initrd][bootconfig][padding][size(le32)][checksum(le32)][#BOOTCONFIG\n]
+
+大小和校驗值爲小端序存放的32位無符號值。
+
+當引導配置被加到initrd鏡像時,整個文件大小會對齊到4字節。空字符( ``\0`` )
+會填補對齊空隙。因此 ``size`` 就是引導配置文件的長度+填充的字節。
+
+Linux內核在內存中解碼initrd鏡像的最後部分以獲取引導配置數據。由於這種“揹負式”
+的方法,只要引導加載器傳遞了正確的initrd文件大小,就無需更改或更新引導加載器
+和內核鏡像本身。如果引導加載器意外傳遞了更長的大小,內核將無法找到引導配置數
+據。
+
+Linux內核在tools/bootconfig下提供了 ``bootconfig`` 命令來完成此操作,管理員
+可以用它從initrd鏡像中刪除或追加配置文件。你可以用以下命令來構建它::
+
+ # make -C tools/bootconfig
+
+要向initrd鏡像添加你的引導配置文件,請按如下命令操作(舊數據會自動移除)::
+
+ # tools/bootconfig/bootconfig -a your-config /boot/initrd.img-X.Y.Z
+
+要從鏡像中移除配置,可以使用-d選項::
+
+ # tools/bootconfig/bootconfig -d /boot/initrd.img-X.Y.Z
+
+然後在內核命令行上添加 ``bootconfig`` 告訴內核去initrd文件末尾尋找內核配置。
+
+將引導配置嵌入內核
+------------------
+
+如果你不能使用initrd,也可以通過Kconfig選項將引導配置文件嵌入內核中。在此情
+況下,你需要用以下選項重新編譯內核::
+
+ CONFIG_BOOT_CONFIG_EMBED=y
+ CONFIG_BOOT_CONFIG_EMBED_FILE="/引導配置/文件/的/路徑"
+
+``CONFIG_BOOT_CONFIG_EMBED_FILE`` 需要從源碼樹或對象樹開始的引導配置文件的
+絕對/相對路徑。內核會將其嵌入作爲默認引導配置。
+
+與將引導配置附加到initrd一樣,你也需要在內核命令行上添加 ``bootconfig`` 告訴
+內核去啓用內嵌的引導配置。
+
+注意,即使你已經設置了此選項,仍可用附加到initrd的其他引導配置覆蓋內嵌的引導
+配置。
+
+通過引導配置傳遞內核參數
+========================
+
+除了內核命令行,引導配置也可以用於傳遞內核參數。所有 ``kernel`` 關鍵字下的鍵
+值對都將直接傳遞給內核命令行。此外, ``init`` 下的鍵值對將通過命令行傳遞給
+init進程。參數按以下順序與用戶給定的內核命令行字符串相連,因此命令行參數可以
+覆蓋引導配置參數(這取決於子系統如何處理參數,但通常前面的參數將被後面的參數
+覆蓋)::
+
+ [bootconfig params][cmdline params] -- [bootconfig init params][cmdline init params]
+
+如果引導配置文件給出的kernel/init參數是::
+
+ kernel {
+   root = 01234567-89ab-cdef-0123-456789abcd
+ }
+ init {
+  splash
+ }
+
+這將被複制到內核命令行字符串中,如下所示::
+
+ root="01234567-89ab-cdef-0123-456789abcd" -- splash
+
+如果用戶給出的其他命令行是::
+
+ ro bootconfig -- quiet
+
+則最後的內核命令行如下::
+
+ root="01234567-89ab-cdef-0123-456789abcd" ro bootconfig -- splash quiet
+
+
+配置文件的限制
+==============
+
+當前最大的配置大小是32KB,關鍵字總數(不是鍵值條目)必須少於1024個節點。
+注意:這不是條目數而是節點數,條目必須消耗超過2個節點(一個關鍵字和一個值)。
+所以從理論上講最多512個鍵值對。如果關鍵字平均包含3個單詞,則可有256個鍵值對。
+在大多數情況下,配置項的數量將少於100個條目,小於8KB,因此這應該足夠了。如果
+節點數超過1024,解析器將返回錯誤,即使文件大小小於32KB。(請注意,此最大尺寸
+不包括填充的空字符。)
+無論如何,因爲 ``bootconfig`` 命令在附加啓動配置到initrd映像時會驗證它,用戶
+可以在引導之前注意到它。
+
+
+引導配置API
+===========
+
+用戶可以查詢或遍歷鍵值對,也可以查找(前綴)根關鍵字節點,並在查找該節點下的
+鍵值。
+
+如果您有一個關鍵字字符串,則可以直接使用 xbc_find_value() 查詢該鍵的值。如果
+你想知道引導配置裏有哪些關鍵字,可以使用 xbc_for_each_key_value() 迭代鍵值對。
+請注意,您需要使用 xbc_array_for_each_value() 訪問數組的值,例如::
+
+ vnode = NULL;
+ xbc_find_value("key.word", &vnode);
+ if (vnode && xbc_node_is_array(vnode))
+    xbc_array_for_each_value(vnode, value) {
+      printk("%s ", value);
+    }
+
+如果您想查找具有前綴字符串的鍵,可以使用 xbc_find_node() 通過前綴字符串查找
+節點,然後用 xbc_node_for_each_key_value() 迭代前綴節點下的鍵。
+
+但最典型的用法是獲取前綴下的命名值或前綴下的命名數組,例如::
+
+ root = xbc_find_node("key.prefix");
+ value = xbc_node_find_value(root, "option", &vnode);
+ ...
+ xbc_node_for_each_array_value(root, "array-option", value, anode) {
+    ...
+ }
+
+這將訪問值“key.prefix.option”的值和“key.prefix.array-option”的數組。
+
+鎖是不需要的,因爲在初始化之後配置只讀。如果需要修改,必須複製所有數據和關鍵字。
+
+
+函數與結構體
+============
+
+相關定義的kernel-doc參見:
+
+ - include/linux/bootconfig.h
+ - lib/bootconfig.c
+
diff --git a/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst b/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst
index 41a39aebb8d6..3f10a9f8f223 100644
--- a/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst
+++ b/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst
@@ -7,7 +7,7 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 二分(bisect)缺陷
 +++++++++++++++++++
@@ -17,14 +17,14 @@
 引言
 =====
 
-始終嘗試由來自kernel.org的原始碼構建的最新內核。如果您沒有信心這樣做,請將
+始終嘗試由來自kernel.org的源代碼構建的最新內核。如果您沒有信心這樣做,請將
 錯誤報告給您的發行版供應商,而不是內核開發人員。
 
 找到缺陷(bug)並不總是那麼容易,不過仍然得去找。如果你找不到它,不要放棄。
-儘可能多的向相關維護人員報告您發現的信息。請參閱MAINTAINERS文件以了解您所
+儘可能多的向相關維護人員報告您發現的信息。請參閱MAINTAINERS文件以瞭解您所
 關注的子系統的維護人員。
 
-在提交錯誤報告之前,請閱讀「Documentation/admin-guide/reporting-issues.rst」。
+在提交錯誤報告之前,請閱讀“Documentation/admin-guide/reporting-issues.rst”。
 
 設備未出現(Devices not appearing)
 ====================================
@@ -38,7 +38,7 @@
 
 操作步驟:
 
-- 從git原始碼構建內核
+- 從git源代碼構建內核
 - 以此開始二分 [#f1]_::
 
 	$ git bisect start
@@ -76,7 +76,7 @@
 如需進一步參考,請閱讀:
 
 - ``git-bisect`` 的手冊頁
-- `Fighting regressions with git bisect(用git bisect解決回歸)
+- `Fighting regressions with git bisect(用git bisect解決迴歸)
   <https://www.kernel.org/pub/software/scm/git/docs/git-bisect-lk2009.html>`_
 - `Fully automated bisecting with "git bisect run"(使用git bisect run
   來全自動二分) <https://lwn.net/Articles/317154>`_
diff --git a/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst b/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst
index 4d813aec77d2..631fd2650929 100644
--- a/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst
+++ b/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst
@@ -7,7 +7,7 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 追蹤缺陷
 =========
@@ -48,8 +48,8 @@
 	 [<c1549f43>] ? sysenter_past_esp+0x40/0x6a
 	---[ end trace 6ebc60ef3981792f ]---
 
-這樣的堆棧跟蹤提供了足夠的信息來識別內核原始碼中發生錯誤的那一行。根據問題的
-嚴重性,它還可能包含 **「Oops」** 一詞,比如::
+這樣的堆棧跟蹤提供了足夠的信息來識別內核源代碼中發生錯誤的那一行。根據問題的
+嚴重性,它還可能包含 **“Oops”** 一詞,比如::
 
 	BUG: unable to handle kernel NULL pointer dereference at   (null)
 	IP: [<c06969d4>] iret_exc+0x7d0/0xa59
@@ -58,17 +58,17 @@
 	...
 
 儘管有 **Oops** 或其他類型的堆棧跟蹤,但通常需要找到出問題的行來識別和處理缺
-陷。在本章中,我們將參考「Oops」來了解需要分析的各種堆棧跟蹤。
+陷。在本章中,我們將參考“Oops”來了解需要分析的各種堆棧跟蹤。
 
 如果內核是用 ``CONFIG_DEBUG_INFO`` 編譯的,那麼可以使用文件:
 `scripts/decode_stacktrace.sh` 。
 
-連結的模塊
+鏈接的模塊
 -----------
 
-受到汙染或正在加載/卸載的模塊用「(…)」標記,汙染標誌在
-`Documentation/admin-guide/tainted-kernels.rst` 文件中進行了描述,「正在被加
-載」用「+」標註,「正在被卸載」用「-」標註。
+受到污染或正在加載/卸載的模塊用“(…)”標記,污染標誌在
+`Documentation/admin-guide/tainted-kernels.rst` 文件中進行了描述,“正在被加
+載”用“+”標註,“正在被卸載”用“-”標註。
 
 
 Oops消息在哪?
@@ -81,19 +81,19 @@ syslog文件,通常是 ``/var/log/messages`` (取決於 ``/etc/syslog.conf``
 
 有時 ``klogd`` 會掛掉,這種情況下您可以運行 ``dmesg > file`` 從內核緩衝區
 讀取數據並保存它。或者您可以 ``cat /proc/kmsg > file`` ,但是您必須適時
-中斷以停止傳輸,因爲 ``kmsg`` 是一個「永無止境的文件」。
+中斷以停止傳輸,因爲 ``kmsg`` 是一個“永無止境的文件”。
 
-如果機器嚴重崩潰,無法輸入命令或磁碟不可用,那還有三個選項:
+如果機器嚴重崩潰,無法輸入命令或磁盤不可用,那還有三個選項:
 
 (1) 手動複製屏幕上的文本,並在機器重新啓動後輸入。很難受,但這是突然崩潰下
-    唯一的選擇。或者你可以用數位相機拍下屏幕——雖然不那麼好,但總比什麼都沒
-    有好。如果消息滾動超出控制台頂部,使用更高解析度(例如 ``vga=791`` )
-    引導啓動將允許您閱讀更多文本。(警告:這需要 ``vesafb`` ,因此對「早期」
+    唯一的選擇。或者你可以用數碼相機拍下屏幕——雖然不那麼好,但總比什麼都沒
+    有好。如果消息滾動超出控制檯頂部,使用更高分辨率(例如 ``vga=791`` )
+    引導啓動將允許您閱讀更多文本。(警告:這需要 ``vesafb`` ,因此對“早期”
     的Oppses沒有幫助)
 
 (2) 從串口終端啓動(參見
     :ref:`Documentation/admin-guide/serial-console.rst <serial_console>` ),
-    在另一台機器上運行數據機然後用你喜歡的通信程序捕獲輸出。
+    在另一臺機器上運行調制解調器然後用你喜歡的通信程序捕獲輸出。
     Minicom運行良好。
 
 (3) 使用Kdump(參閱 Documentation/admin-guide/kdump/kdump.rst ),使用
@@ -103,7 +103,7 @@ syslog文件,通常是 ``/var/log/messages`` (取決於 ``/etc/syslog.conf``
 找到缺陷位置
 -------------
 
-如果你能指出缺陷在內核原始碼中的位置,則報告缺陷的效果會非常好。這有兩種方法。
+如果你能指出缺陷在內核源代碼中的位置,則報告缺陷的效果會非常好。這有兩種方法。
 通常來說使用 ``gdb`` 會比較容易,不過內核需要用調試信息來預編譯。
 
 gdb
@@ -187,7 +187,7 @@ GNU 調試器(GNU debugger, ``gdb`` )是從 ``vmlinux`` 文件中找出OOP
 objdump
 ^^^^^^^^
 
-要調試內核,請使用objdump並從崩潰輸出中查找十六進位偏移,以找到有效的代碼/匯
+要調試內核,請使用objdump並從崩潰輸出中查找十六進制偏移,以找到有效的代碼/匯
 編行。如果沒有調試符號,您將看到所示例程的彙編程序代碼,但是如果內核有調試
 符號,C代碼也將可見(調試符號可以在內核配置菜單的hacking項中啓用)。例如::
 
@@ -197,7 +197,7 @@ objdump
 
    您需要處於內核樹的頂層以便此獲得您的C文件。
 
-如果您無法訪問原始碼,仍然可以使用以下方法調試一些崩潰轉儲(如Dave Miller的
+如果您無法訪問源代碼,仍然可以使用以下方法調試一些崩潰轉儲(如Dave Miller的
 示例崩潰轉儲輸出所示)::
 
      EIP is at 	+0x14/0x4c0
@@ -234,9 +234,9 @@ objdump
 報告缺陷
 ---------
 
-一旦你通過定位缺陷找到了其發生的地方,你可以嘗試自己修復它或者向上游報告它。
+一旦你通過定位缺陷找到了其發生的地方,你可以嘗試自己修復它或者向上遊報告它。
 
-爲了向上游報告,您應該找出用於開發受影響代碼的郵件列表。這可以使用 ``get_maintainer.pl`` 。
+爲了向上遊報告,您應該找出用於開發受影響代碼的郵件列表。這可以使用 ``get_maintainer.pl`` 。
 
 
 例如,您在gspca的sonixj.c文件中發現一個缺陷,則可以通過以下方法找到它的維護者::
@@ -251,7 +251,7 @@ objdump
 
 請注意它將指出:
 
-- 最後接觸原始碼的開發人員(如果這是在git樹中完成的)。在上面的例子中是Tejun
+- 最後接觸源代碼的開發人員(如果這是在git樹中完成的)。在上面的例子中是Tejun
   和Bhaktipriya(在這個特定的案例中,沒有人真正參與這個文件的開發);
 - 驅動維護人員(Hans Verkuil);
 - 子系統維護人員(Mauro Carvalho Chehab);
diff --git a/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst b/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst
index bdc1a22046cf..6961006b4a2d 100644
--- a/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst
+++ b/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst
@@ -2,15 +2,15 @@
 
 .. include:: ../disclaimer-zh_TW.rst
 
-:Translator: 胡皓文 Hu Haowen <src.res@email.cn>
+:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 清除 WARN_ONCE
 --------------
 
-WARN_ONCE / WARN_ON_ONCE / printk_once 僅僅列印一次消息.
+WARN_ONCE / WARN_ON_ONCE / printk_once 僅僅打印一次消息.
 
 echo 1 > /sys/kernel/debug/clear_warn_once
 
-可以清除這種狀態並且再次允許列印一次告警信息,這對於運行測試集後重現問題
+可以清除這種狀態並且再次允許打印一次告警信息,這對於運行測試集後重現問題
 很有用。
 
diff --git a/Documentation/translations/zh_TW/admin-guide/cpu-load.rst b/Documentation/translations/zh_TW/admin-guide/cpu-load.rst
index be087cef1967..cc046f3b7ffa 100644
--- a/Documentation/translations/zh_TW/admin-guide/cpu-load.rst
+++ b/Documentation/translations/zh_TW/admin-guide/cpu-load.rst
@@ -2,7 +2,7 @@
 
 .. include:: ../disclaimer-zh_TW.rst
 
-:Translator: 胡皓文 Hu Haowen <src.res@email.cn>
+:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 ========
 CPU 負載
@@ -20,13 +20,13 @@ Linux通過``/proc/stat``和``/proc/uptime``導出各種信息,用戶空間工
 
     ...
 
-這裡系統認爲在默認採樣周期內有10.01%的時間工作在用戶空間,2.92%的時
+這裏系統認爲在默認採樣週期內有10.01%的時間工作在用戶空間,2.92%的時
 間用在系統空間,總體上有81.63%的時間是空閒的。
 
 大多數情況下``/proc/stat``的信息幾乎真實反映了系統信息,然而,由於內
 核採集這些數據的方式/時間的特點,有時這些信息根本不可靠。
 
-那麼這些信息是如何被搜集的呢?每當時間中斷觸發時,內核查看此刻運行的
+那麼這些信息是如何被蒐集的呢?每當時間中斷觸發時,內核查看此刻運行的
 進程類型,並增加與此類型/狀態進程對應的計數器的值。這種方法的問題是
 在兩次時間中斷之間系統(進程)能夠在多種狀態之間切換多次,而計數器只
 增加最後一種狀態下的計數。
@@ -34,7 +34,7 @@ Linux通過``/proc/stat``和``/proc/uptime``導出各種信息,用戶空間工
 舉例
 ---
 
-假設系統有一個進程以如下方式周期性地占用cpu::
+假設系統有一個進程以如下方式週期性地佔用cpu::
 
      兩個時鐘中斷之間的時間線
     |-----------------------|
@@ -46,7 +46,7 @@ Linux通過``/proc/stat``和``/proc/uptime``導出各種信息,用戶空間工
 在上面的情況下,根據``/proc/stat``的信息(由於當系統處於空閒狀態時,
 時間中斷經常會發生)系統的負載將會是0
 
-大家能夠想像內核的這種行爲會發生在許多情況下,這將導致``/proc/stat``
+大家能夠想象內核的這種行爲會發生在許多情況下,這將導致``/proc/stat``
 中存在相當古怪的信息::
 
 	/* gcc -o hog smallhog.c */
diff --git a/Documentation/translations/zh_TW/admin-guide/cputopology.rst b/Documentation/translations/zh_TW/admin-guide/cputopology.rst
new file mode 100644
index 000000000000..147a286e517c
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/cputopology.rst
@@ -0,0 +1,98 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/cputopology.rst
+
+:翻譯:
+
+  唐藝舟 Tang Yizhou <tangyeechou@gmail.com>
+
+==========================
+如何通過sysfs將CPU拓撲導出
+==========================
+
+CPU拓撲信息通過sysfs導出。顯示的項(屬性)和某些架構的/proc/cpuinfo輸出相似。它們位於
+/sys/devices/system/cpu/cpuX/topology/。請閱讀ABI文件:
+Documentation/ABI/stable/sysfs-devices-system-cpu。
+
+drivers/base/topology.c是體系結構中性的,它導出了這些屬性。然而,die、cluster、book、
+draw這些層次結構相關的文件僅在體系結構提供了下文描述的宏的條件下被創建。
+
+對於支持這個特性的體系結構,它必須在include/asm-XXX/topology.h中定義這些宏中的一部分::
+
+	#define topology_physical_package_id(cpu)
+	#define topology_die_id(cpu)
+	#define topology_cluster_id(cpu)
+	#define topology_core_id(cpu)
+	#define topology_book_id(cpu)
+	#define topology_drawer_id(cpu)
+	#define topology_sibling_cpumask(cpu)
+	#define topology_core_cpumask(cpu)
+	#define topology_cluster_cpumask(cpu)
+	#define topology_die_cpumask(cpu)
+	#define topology_book_cpumask(cpu)
+	#define topology_drawer_cpumask(cpu)
+
+``**_id macros`` 的類型是int。
+``**_cpumask macros`` 的類型是 ``(const) struct cpumask *`` 。後者和恰當的
+``**_siblings`` sysfs屬性對應(除了topology_sibling_cpumask(),它和thread_siblings
+對應)。
+
+爲了在所有體系結構上保持一致,include/linux/topology.h提供了上述所有宏的默認定義,以防
+它們未在include/asm-XXX/topology.h中定義:
+
+1) topology_physical_package_id: -1
+2) topology_die_id: -1
+3) topology_cluster_id: -1
+4) topology_core_id: 0
+5) topology_book_id: -1
+6) topology_drawer_id: -1
+7) topology_sibling_cpumask: 僅入參CPU
+8) topology_core_cpumask: 僅入參CPU
+9) topology_cluster_cpumask: 僅入參CPU
+10) topology_die_cpumask: 僅入參CPU
+11) topology_book_cpumask:  僅入參CPU
+12) topology_drawer_cpumask: 僅入參CPU
+
+此外,CPU拓撲信息由/sys/devices/system/cpu提供,包含下述文件。輸出對應的內部數據源放在
+方括號("[]")中。
+
+    =========== ==================================================================
+    kernel_max: 內核配置允許的最大CPU下標值。[NR_CPUS-1]
+
+    offline:    由於熱插拔移除或者超過內核允許的CPU上限(上文描述的kernel_max)
+                導致未上線的CPU。[~cpu_online_mask + cpus >= NR_CPUS]
+
+    online:     在線的CPU,可供調度使用。[cpu_online_mask]
+
+    possible:   已被分配資源的CPU,如果它們CPU實際存在,可以上線。
+                [cpu_possible_mask]
+
+    present:    被系統識別實際存在的CPU。[cpu_present_mask]
+    =========== ==================================================================
+
+上述輸出的格式和cpulist_parse()兼容[參見 <linux/cpumask.h>]。下面給些例子。
+
+在本例中,系統中有64個CPU,但是CPU 32-63超過了kernel_max值,因爲NR_CPUS配置項是32,
+取值範圍被限制爲0..31。此外注意CPU2和4-31未上線,但是可以上線,因爲它們同時存在於
+present和possible::
+
+     kernel_max: 31
+        offline: 2,4-31,32-63
+         online: 0-1,3
+       possible: 0-31
+        present: 0-31
+
+在本例中,NR_CPUS配置項是128,但內核啓動時設置possible_cpus=144。系統中有4個CPU,
+CPU2被手動設置下線(也是唯一一個可以上線的CPU)::
+
+     kernel_max: 127
+        offline: 2,4-127,128-143
+         online: 0-1,3
+       possible: 0-127
+        present: 0-3
+
+閱讀Documentation/core-api/cpu_hotplug.rst可瞭解開機參數possible_cpus=NUM,同時還
+可以瞭解各種cpumask的信息。
+
diff --git a/Documentation/translations/zh_TW/admin-guide/index.rst b/Documentation/translations/zh_TW/admin-guide/index.rst
index 293c20245783..b51ddf760c4d 100644
--- a/Documentation/translations/zh_TW/admin-guide/index.rst
+++ b/Documentation/translations/zh_TW/admin-guide/index.rst
@@ -3,13 +3,13 @@
 .. include:: ../disclaimer-zh_TW.rst
 
 :Original: :doc:`../../../admin-guide/index`
-:Translator: 胡皓文 Hu Haowen <src.res@email.cn>
+:Translator: 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 Linux 內核用戶和管理員指南
 ==========================
 
 下面是一組隨時間添加到內核中的面向用戶的文檔的集合。到目前爲止,還沒有一個
-整體的順序或組織 - 這些材料不是一個單一的,連貫的文件!幸運的話,情況會隨著
+整體的順序或組織 - 這些材料不是一個單一的,連貫的文件!幸運的話,情況會隨着
 時間的推移而迅速改善。
 
 這個初始部分包含總體信息,包括描述內核的README, 關於內核參數的文檔等。
@@ -21,15 +21,15 @@ Linux 內核用戶和管理員指南
 
 Todolist:
 
-   kernel-parameters
-   devices
-   sysctl/index
+*   kernel-parameters
+*   devices
+*   sysctl/index
 
 本節介紹CPU漏洞及其緩解措施。
 
 Todolist:
 
-   hw-vuln/index
+*   hw-vuln/index
 
 下面的一組文檔,針對的是試圖跟蹤問題和bug的用戶。
 
@@ -37,6 +37,7 @@ Todolist:
    :maxdepth: 1
 
    reporting-issues
+   reporting-regressions
    security-bugs
    bug-hunting
    bug-bisect
@@ -45,18 +46,17 @@ Todolist:
 
 Todolist:
 
-   reporting-bugs
-   ramoops
-   dynamic-debug-howto
-   kdump/index
-   perf/index
+*   ramoops
+*   dynamic-debug-howto
+*   kdump/index
+*   perf/index
 
-這是應用程式開發人員感興趣的章節的開始。可以在這裡找到涵蓋內核ABI各個
+這是應用程序開發人員感興趣的章節的開始。可以在這裏找到涵蓋內核ABI各個
 方面的文檔。
 
 Todolist:
 
-   sysfs-rules
+*   sysfs-rules
 
 本手冊的其餘部分包括各種指南,介紹如何根據您的喜好配置內核的特定行爲。
 
@@ -64,67 +64,67 @@ Todolist:
 .. toctree::
    :maxdepth: 1
 
+   bootconfig
    clearing-warn-once
    cpu-load
+   cputopology
+   lockup-watchdogs
    unicode
+   sysrq
+   mm/index
 
 Todolist:
 
-   acpi/index
-   aoe/index
-   auxdisplay/index
-   bcache
-   binderfs
-   binfmt-misc
-   blockdev/index
-   bootconfig
-   braille-console
-   btmrvl
-   cgroup-v1/index
-   cgroup-v2
-   cifs/index
-   cputopology
-   dell_rbu
-   device-mapper/index
-   edid
-   efi-stub
-   ext4
-   nfs/index
-   gpio/index
-   highuid
-   hw_random
-   initrd
-   iostats
-   java
-   jfs
-   kernel-per-CPU-kthreads
-   laptops/index
-   lcd-panel-cgram
-   ldm
-   lockup-watchdogs
-   LSM/index
-   md
-   media/index
-   mm/index
-   module-signing
-   mono
-   namespaces/index
-   numastat
-   parport
-   perf-security
-   pm/index
-   pnp
-   rapidio
-   ras
-   rtc
-   serial-console
-   svga
-   sysrq
-   thunderbolt
-   ufs
-   vga-softcursor
-   video-output
-   xfs
+*   acpi/index
+*   aoe/index
+*   auxdisplay/index
+*   bcache
+*   binderfs
+*   binfmt-misc
+*   blockdev/index
+*   braille-console
+*   btmrvl
+*   cgroup-v1/index
+*   cgroup-v2
+*   cifs/index
+*   dell_rbu
+*   device-mapper/index
+*   edid
+*   efi-stub
+*   ext4
+*   nfs/index
+*   gpio/index
+*   highuid
+*   hw_random
+*   initrd
+*   iostats
+*   java
+*   jfs
+*   kernel-per-CPU-kthreads
+*   laptops/index
+*   lcd-panel-cgram
+*   ldm
+*   LSM/index
+*   md
+*   media/index
+*   module-signing
+*   mono
+*   namespaces/index
+*   numastat
+*   parport
+*   perf-security
+*   pm/index
+*   pnp
+*   rapidio
+*   ras
+*   rtc
+*   serial-console
+*   svga
+*   thunderbolt
+*   ufs
+*   vga-softcursor
+*   video-output
+*   xfs
 
 .. only::  subproject and html
 
diff --git a/Documentation/translations/zh_TW/admin-guide/init.rst b/Documentation/translations/zh_TW/admin-guide/init.rst
index 32cdf134948f..be6e34f5f7fa 100644
--- a/Documentation/translations/zh_TW/admin-guide/init.rst
+++ b/Documentation/translations/zh_TW/admin-guide/init.rst
@@ -7,10 +7,10 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
-解釋「No working init found.」啓動掛起消息
-==========================================
+解釋“No working init found.”啓動掛起消息
+=========================================
 
 :作者:
 
@@ -18,41 +18,41 @@
 
  Cristian Souza <cristianmsbr at gmail period com>
 
-本文檔提供了加載初始化二進位(init binary)失敗的一些高層級原因(大致按執行
+本文檔提供了加載初始化二進制(init binary)失敗的一些高層級原因(大致按執行
 順序列出)。
 
-1) **無法掛載根文件系統Unable to mount root FS** :請設置「debug」內核參數(在
+1) **無法掛載根文件系統Unable to mount root FS** :請設置“debug”內核參數(在
    引導加載程序bootloader配置文件或CONFIG_CMDLINE)以獲取更詳細的內核消息。
 
-2) **初始化二進位不存在於根文件系統上init binary doesn't exist on rootfs** :
+2) **初始化二進制不存在於根文件系統上init binary doesn't exist on rootfs** :
    確保您的根文件系統類型正確(並且 ``root=`` 內核參數指向正確的分區);擁有
-   所需的驅動程序,例如SCSI或USB等存儲硬體;文件系統(ext3、jffs2等)是內建的
+   所需的驅動程序,例如SCSI或USB等存儲硬件;文件系統(ext3、jffs2等)是內建的
    (或者作爲模塊由initrd預加載)。
 
-3) **控制台設備損壞Broken console device** : ``console= setup`` 中可能存在
-   衝突 --> 初始控制台不可用(initial console unavailable)。例如,由於串行
-   IRQ問題(如缺少基於中斷的配置)導致的某些串行控制台不可靠。嘗試使用不同的
+3) **控制檯設備損壞Broken console device** : ``console= setup`` 中可能存在
+   衝突 --> 初始控制檯不可用(initial console unavailable)。例如,由於串行
+   IRQ問題(如缺少基於中斷的配置)導致的某些串行控制檯不可靠。嘗試使用不同的
    ``console= device`` 或像 ``netconsole=`` 。
 
-4) **二進位存在但依賴項不可用Binary exists but dependencies not available** :
-   例如初始化二進位的必需庫依賴項,像 ``/lib/ld-linux.so.2`` 丟失或損壞。使用
+4) **二進制存在但依賴項不可用Binary exists but dependencies not available** :
+   例如初始化二進制的必需庫依賴項,像 ``/lib/ld-linux.so.2`` 丟失或損壞。使用
    ``readelf -d <INIT>|grep NEEDED`` 找出需要哪些庫。
 
-5) **無法加載二進位Binary cannot be loaded** :請確保二進位的體系結構與您的
-   硬體匹配。例如i386不匹配x86_64,或者嘗試在ARM硬體上加載x86。如果您嘗試在
-   此處加載非二進位文件(shell腳本?),您應該確保腳本在其工作頭(shebang
+5) **無法加載二進制Binary cannot be loaded** :請確保二進制的體系結構與您的
+   硬件匹配。例如i386不匹配x86_64,或者嘗試在ARM硬件上加載x86。如果您嘗試在
+   此處加載非二進制文件(shell腳本?),您應該確保腳本在其工作頭(shebang
    header)行 ``#!/...`` 中指定能正常工作的解釋器(包括其庫依賴項)。在處理
-   腳本之前,最好先測試一個簡單的非腳本二進位文件,比如 ``/bin/sh`` ,並確認
+   腳本之前,最好先測試一個簡單的非腳本二進制文件,比如 ``/bin/sh`` ,並確認
    它能成功執行。要了解更多信息,請將代碼添加到 ``init/main.c`` 以顯示
    kernel_execve()的返回值。
 
-當您發現新的失敗原因時,請擴展本解釋(畢竟加載初始化二進位是一個 **關鍵** 且
+當您發現新的失敗原因時,請擴展本解釋(畢竟加載初始化二進制是一個 **關鍵** 且
 艱難的過渡步驟,需要儘可能無痛地進行),然後向LKML提交一個補丁。
 
 待辦事項:
 
 - 通過一個可以存儲 ``kernel_execve()`` 結果值的結構體數組實現各種
-  ``run_init_process()`` 調用,並在失敗時通過疊代 **所有** 結果來記錄一切
+  ``run_init_process()`` 調用,並在失敗時通過迭代 **所有** 結果來記錄一切
   (非常重要的可用性修復)。
-- 試著使實現本身在一般情況下更有幫助,例如在受影響的地方提供額外的錯誤消息。
+- 試着使實現本身在一般情況下更有幫助,例如在受影響的地方提供額外的錯誤消息。
 
diff --git a/Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst b/Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst
new file mode 100644
index 000000000000..64a28637c853
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/lockup-watchdogs.rst
@@ -0,0 +1,69 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/lockup-watchdogs.rst
+:Translator: Hailong Liu <liu.hailong6@zte.com.cn>
+
+.. _tw_lockup-watchdogs:
+
+
+=================================================
+Softlockup與hardlockup檢測機制(又名:nmi_watchdog)
+=================================================
+
+Linux中內核實現了一種用以檢測系統發生softlockup和hardlockup的看門狗機制。
+
+Softlockup是一種會引發系統在內核態中一直循環超過20秒(詳見下面“實現”小節)導致
+其他任務沒有機會得到運行的BUG。一旦檢測到'softlockup'發生,默認情況下系統會打
+印當前堆棧跟蹤信息並進入鎖定狀態。也可配置使其在檢測到'softlockup'後進入panic
+狀態;通過sysctl命令設置“kernel.softlockup_panic”、使用內核啓動參數
+“softlockup_panic”(詳見Documentation/admin-guide/kernel-parameters.rst)以及使
+能內核編譯選項“BOOTPARAM_SOFTLOCKUP_PANIC”都可實現這種配置。
+
+而'hardlockup'是一種會引發系統在內核態一直循環超過10秒鐘(詳見"實現"小節)導致其
+他中斷沒有機會運行的缺陷。與'softlockup'情況類似,除了使用sysctl命令設置
+'hardlockup_panic'、使能內核選項“BOOTPARAM_HARDLOCKUP_PANIC”以及使用內核參數
+"nmi_watchdog"(詳見:”Documentation/admin-guide/kernel-parameters.rst“)外,一旦檢
+測到'hardlockup'默認情況下系統打印當前堆棧跟蹤信息,然後進入鎖定狀態。
+
+這個panic選項也可以與panic_timeout結合使用(這個panic_timeout是通過稍具迷惑性的
+sysctl命令"kernel.panic"來設置),使系統在panic指定時間後自動重啓。
+
+實現
+====
+
+Softlockup和hardlockup分別建立在hrtimer(高精度定時器)和perf兩個子系統上而實現。
+這也就意味着理論上任何架構只要實現了這兩個子系統就支持這兩種檢測機制。
+
+Hrtimer用於週期性產生中斷並喚醒watchdog線程;NMI perf事件則以”watchdog_thresh“
+(編譯時默認初始化爲10秒,也可通過”watchdog_thresh“這個sysctl接口來進行配置修改)
+爲間隔週期產生以檢測 hardlockups。如果一個CPU在這個時間段內沒有檢測到hrtimer中
+斷髮生,'hardlockup 檢測器'(即NMI perf事件處理函數)將會視系統配置而選擇產生內核
+警告或者直接panic。
+
+而watchdog線程本質上是一個高優先級內核線程,每調度一次就對時間戳進行一次更新。
+如果時間戳在2*watchdog_thresh(這個是softlockup的觸發門限)這段時間都未更新,那麼
+"softlocup 檢測器"(內部hrtimer定時器回調函數)會將相關的調試信息打印到系統日誌中,
+然後如果系統配置了進入panic流程則進入panic,否則內核繼續執行。
+
+Hrtimer定時器的週期是2*watchdog_thresh/5,也就是說在hardlockup被觸發前hrtimer有
+2~3次機會產生時鐘中斷。
+
+如上所述,內核相當於爲系統管理員提供了一個可調節hrtimer定時器和perf事件週期長度
+的調節旋鈕。如何通過這個旋鈕爲特定使用場景配置一個合理的週期值要對lockups檢測的
+響應速度和lockups檢測開銷這二者之間進行權衡。
+
+默認情況下所有在線cpu上都會運行一個watchdog線程。不過在內核配置了”NO_HZ_FULL“的
+情況下watchdog線程默認只會運行在管家(housekeeping)cpu上,而”nohz_full“啓動參數指
+定的cpu上則不會有watchdog線程運行。試想,如果我們允許watchdog線程在”nohz_full“指
+定的cpu上運行,這些cpu上必須得運行時鐘定時器來激發watchdog線程調度;這樣一來就會
+使”nohz_full“保護用戶程序免受內核干擾的功能失效。當然,副作用就是”nohz_full“指定
+的cpu即使在內核產生了lockup問題我們也無法檢測到。不過,至少我們可以允許watchdog
+線程在管家(non-tickless)核上繼續運行以便我們能繼續正常的監測這些cpus上的lockups
+事件。
+
+不論哪種情況都可以通過sysctl命令kernel.watchdog_cpumask來對沒有運行watchdog線程
+的cpu集合進行調節。對於nohz_full而言,如果nohz_full cpu上有異常掛住的情況,通過
+這種方式打開這些cpu上的watchdog進行調試可能會有所作用。
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst
new file mode 100644
index 000000000000..1900692f1c75
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/index.rst
@@ -0,0 +1,31 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/index.rst
+
+:翻譯:
+
+ 司延騰 Yanteng Si <siyanteng@loongson.cn>
+
+:校譯:
+
+============
+監測數據訪問
+============
+
+:doc:`DAMON </mm/damon/index>` 允許輕量級的數據訪問監測。使用DAMON,
+用戶可以分析他們系統的內存訪問模式,並優化它們。
+
+.. toctree::
+   :maxdepth: 2
+
+   start
+   usage
+   reclaim
+   lru_sort
+
+
+
+
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst
new file mode 100644
index 000000000000..01cea8784b6e
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/lru_sort.rst
@@ -0,0 +1,265 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/lru_sort.rst
+
+:翻譯:
+
+ 臧雷剛 Leigang Zang <zangleigang@hisilicon.com>
+
+:校譯:
+
+==================
+基於DAMON的LRU排序
+==================
+
+基於DAMON的LRU排序是一個靜態的內核模塊,旨在用於以主動的、輕量級的數據訪問模型
+爲基礎的頁面優先級處理的LRU鏈表上,以使得LRU上的數據訪問模型更爲可信。
+
+哪裏需要主動的LRU排序
+=====================
+
+在一個大型系統中,以頁爲粒度的訪問檢測會有比較顯著的開銷,LRU通常不會主動去排序,
+而是對部分特殊事件進行部分的、響應式的排序,例如:特殊的用戶請求,系統調用或者
+內存壓力。這導致,在有些場景下,LRU不能夠完美的作爲一個可信的數據訪問模型,比如
+在內存壓力下對目標內存進行回收。
+
+因爲DAMON能夠儘可能準確的識別數據訪問模型,同時只引起用戶指定範圍的開銷,主動的
+執行DAMON_LRU_SORT讓LRU變得更爲可信是有益的,而且這隻需要較少和可控的開銷。
+
+這是如何工作的
+==============
+
+DAMON_LRU_SORT使用DAMON尋找熱頁(範圍內的頁面訪問頻率高於用戶指定的閾值)和冷頁
+(範圍內的頁面在超過用戶指定的時間無訪問),並提高熱頁和降低冷頁在LRU中的優先級。
+爲了避免在排序過程佔用更多的CPU計算資源,可以設置一個CPU佔用時間的約束值。在約
+束下,分別提升或者降低更多的熱頁和冷頁。系統管理員也可以配置三個內存水位以控制
+在何種條件下自動激活或者停止這種機制。
+
+冷熱閾值和CPU約束的默認值是比較保守的。這意味着,在默認參數下,模塊可以廣泛且無
+負作用的使用在常見環境中,同時在只消耗一小部分CPU時間的情況下,給有內存壓力的系
+統提供一定水平的冷熱識別。
+
+接口:模塊參數
+==============
+
+使用此特性,你首先需要確認你的系統中運行的內核在編譯時啓用了
+``CONFIG_DAMON_LRU_SORT=y``.
+
+爲了讓系統管理員打開或者關閉並且調節指定的系統,DAMON_LRU_SORT設計了模塊參數。
+這意味着,你可以添加 ``damon_lru_sort.<parameter>=<value>`` 到內核的啓動命令行
+參數,或者在 ``/sys/modules/damon_lru_sort/parameters/<parameter>`` 寫入正確的
+值。
+
+下邊是每個參數的描述
+
+enabled
+-------
+
+打開或者關閉DAMON_LRU_SORT.
+
+你可以通過設置這個參數爲 ``Y`` 來打開DAMON_LRU_SORT。設置爲 ``N`` 關閉
+DAMON_LRU_SORT。注意,在基於水位的激活的情況下,DAMON_LRU_SORT有可能不會真正去
+監測或者做LRU排序。對這種情況,參考下方關於水位的描述。
+
+commit_inputs
+-------------
+
+讓DAMON_LRU_SORT再次讀取輸入參數,除了 ``enabled`` 。
+
+在DAMON_LRU_SORT運行時,新的輸入參數默認不會被應用。一旦這個參數被設置爲 ``Y``
+,DAMON_LRU_SORT會再次讀取除了 ``enabled`` 之外的參數。讀取完成後,這個參數會被
+設置爲 ``N`` 。如果在讀取時發現有無效參數,DAMON_LRU_SORT會被關閉。
+
+hot_thres_access_freq
+---------------------
+
+熱點內存區域的訪問頻率閾值,千分比。
+
+如果一個內存區域的訪問頻率大於等於這個值,DAMON_LRU_SORT把這個區域看作熱區,並
+在LRU上把這個區域標記爲已訪問,因些在內存壓力下這部分內存不會被回收。默認爲50%。
+
+cold_min_age
+------------
+
+用於識別冷內存區域的時間閾值,單位是微秒。
+
+如果一個內存區域在這個時間內未被訪問過,DAMON_LRU_SORT把這個區域看作冷區,並在
+LRU上把這個區域標記爲未訪問,因此在內存壓力下這些內存會首先被回收。默認值爲120
+秒。
+
+quota_ms
+--------
+
+嘗試LRU鏈表排序的時間限制,單位是毫秒。
+
+DAMON_LRU_SORT在一個時間窗口內(quota_reset_interval_ms)內最多嘗試這麼長時間來
+對LRU進行排序。這個可以用來作爲CPU計算資源的約束。如果值爲0,則表示無限制。
+
+默認10毫秒。
+
+quota_reset_interval_ms
+-----------------------
+
+配額計時重置週期,毫秒。
+
+配額計時重置週期。即,在quota_reset_interval_ms毫秒內,DAMON_LRU_SORT對LRU進行
+排序不會超過quota_ms或者quota_sz。
+
+默認1秒。
+
+wmarks_interval
+---------------
+
+水位的檢查週期,單位是微秒。
+
+當DAMON_LRU_SORT使能但是由於水位而不活躍時檢查水位前最小的等待時間。默認值5秒。
+
+wmarks_high
+-----------
+
+空閒內存高水位,千分比。
+
+如果空閒內存水位高於這個值,DAMON_LRU_SORT停止工作,不做任何事,除了週期性的檢
+查水位。默認200(20%)。
+
+wmarks_mid
+----------
+
+空閒內存中間水位,千分比。
+
+如果空閒內存水位在這個值與低水位之間,DAMON_LRU_SORT開始工作,開始檢測並對LRU鏈
+表進行排序。默認150(15%)。
+
+wmarks_low
+----------
+
+空閒內存低水位,千分比。
+
+如果空閒內存小於這個值,DAMON_LRU_SORT不再工作,不做任何事,除了週期性的檢查水
+線。默認50(5%)。
+
+sample_interval
+---------------
+
+監測的採樣週期,微秒。
+
+DAMON對冷內存監測的採樣週期。更多細節請參考DAMON文檔 (:doc:`usage`) 。默認5
+毫秒。
+
+aggr_interval
+-------------
+
+監測的收集週期,微秒。
+
+DAMON對冷內存進行收集的時間週期。更多細節請參考DAMON文檔 (:doc:`usage`) 。默認
+100毫秒。
+
+min_nr_regions
+--------------
+
+最小監測區域數量。
+
+對冷內存區域監測的最小數量。這個值可以作爲監測質量的下限。不過,這個值設置的過
+大會增加開銷。更多細節請參考DAMON文檔 (:doc:`usage`) 。默認值爲10。
+
+max_nr_regions
+--------------
+
+最大監測區域數量。
+
+對冷內存區域監測的最大數量。這個值可以作爲監測質量的上限。然而,這個值設置的過
+低會導致監測結果變差。更多細節請參考DAMON文檔 (:doc:`usage`) 。默認值爲1000。
+
+monitor_region_start
+--------------------
+
+目標內存區域的起始物理地址。
+
+DAMON_LRU_SORT要處理的目標內存區域的起始物理地址。默認,使用系統最大內存。
+
+monitor_region_end
+------------------
+
+目標內存區域的結束物理地址。
+
+DAMON_LRU_SORT要處理的目標內存區域的結束物理地址。默認,使用系統最大內存。
+
+kdamond_pid
+-----------
+
+DAMON線程的PID。
+
+如果DAMON_LRU_SORT是使能的,這個表示任務線程的PID。其它情況爲-1。
+
+nr_lru_sort_tried_hot_regions
+-----------------------------
+
+被嘗試進行LRU排序的熱內存區域的數量。
+
+bytes_lru_sort_tried_hot_regions
+--------------------------------
+
+被嘗試進行LRU排序的熱內存區域的大小(字節)。
+
+nr_lru_sorted_hot_regions
+-------------------------
+
+成功進行LRU排序的熱內存區域的數量。
+
+bytes_lru_sorted_hot_regions
+----------------------------
+
+成功進行LRU排序的熱內存區域的大小(字節)。
+
+nr_hot_quota_exceeds
+--------------------
+
+熱區域時間約束超過限制的次數。
+
+nr_lru_sort_tried_cold_regions
+------------------------------
+
+被嘗試進行LRU排序的冷內存區域的數量。
+
+bytes_lru_sort_tried_cold_regions
+---------------------------------
+
+被嘗試進行LRU排序的冷內存區域的大小(字節)。
+
+nr_lru_sorted_cold_regions
+--------------------------
+
+成功進行LRU排序的冷內存區域的數量。
+
+bytes_lru_sorted_cold_regions
+-----------------------------
+
+成功進行LRU排序的冷內存區域的大小(字節)。
+
+nr_cold_quota_exceeds
+---------------------
+
+冷區域時間約束超過限制的次數。
+
+Example
+=======
+
+如下是一個運行時的命令示例,使DAMON_LRU_SORT查找訪問頻率超過50%的區域並對其進行
+LRU的優先級的提升,同時降低那些超過120秒無人訪問的內存區域的優先級。優先級的處
+理被限制在最多1%的CPU以避免DAMON_LRU_SORT消費過多CPU時間。在系統空閒內存超過50%
+時DAMON_LRU_SORT停止工作,並在低於40%時重新開始工作。如果DAMON_RECLAIM沒有取得
+進展且空閒內存低於20%,再次讓DAMON_LRU_SORT停止工作,以此回退到以LRU鏈表爲基礎
+以頁面爲單位的內存回收上。 ::
+
+    # cd /sys/modules/damon_lru_sort/parameters
+    # echo 500 > hot_thres_access_freq
+    # echo 120000000 > cold_min_age
+    # echo 10 > quota_ms
+    # echo 1000 > quota_reset_interval_ms
+    # echo 500 > wmarks_high
+    # echo 400 > wmarks_mid
+    # echo 200 > wmarks_low
+    # echo Y > enabled
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst
new file mode 100644
index 000000000000..a390712d5792
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/reclaim.rst
@@ -0,0 +1,230 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/reclaim.rst
+
+:翻譯:
+
+ 司延騰 Yanteng Si <siyanteng@loongson.cn>
+
+:校譯:
+
+===============
+基於DAMON的回收
+===============
+
+基於DAMON的回收(DAMON_RECLAIM)是一個靜態的內核模塊,旨在用於輕度內存壓力下的主動和輕
+量級的回收。它的目的不是取代基於LRU列表的頁面回收,而是有選擇地用於不同程度的內存壓力和要
+求。
+
+哪些地方需要主動回收?
+======================
+
+在一般的內存超量使用(over-committed systems,虛擬化相關術語)的系統上,主動回收冷頁
+有助於節省內存和減少延遲高峯,這些延遲是由直接回收進程或kswapd的CPU消耗引起的,同時只產
+生最小的性能下降 [1]_ [2]_ 。
+
+基於空閒頁報告 [3]_ 的內存過度承諾的虛擬化系統就是很好的例子。在這樣的系統中,客戶機
+向主機報告他們的空閒內存,而主機則將報告的內存重新分配給其他客戶。因此,系統的內存得到了充
+分的利用。然而,客戶可能不那麼節省內存,主要是因爲一些內核子系統和用戶空間應用程序被設計爲
+使用盡可能多的內存。然後,客戶機可能只向主機報告少量的內存是空閒的,導致系統的內存利用率下降。
+在客戶中運行主動回收可以緩解這個問題。
+
+它是如何工作的?
+================
+
+DAMON_RECLAIM找到在特定時間內沒有被訪問的內存區域並分頁。爲了避免它在分頁操作中消耗過多
+的CPU,可以配置一個速度限制。在這個速度限制下,它首先分頁出那些沒有被訪問過的內存區域。系
+統管理員還可以配置在什麼情況下這個方案應該自動激活和停用三個內存壓力水位。
+
+接口: 模塊參數
+==============
+
+要使用這個功能,你首先要確保你的系統運行在一個以 ``CONFIG_DAMON_RECLAIM=y`` 構建的內
+核上。
+
+爲了讓系統管理員啓用或禁用它,併爲給定的系統進行調整,DAMON_RECLAIM利用了模塊參數。也就
+是說,你可以把 ``damon_reclaim.<parameter>=<value>`` 放在內核啓動命令行上,或者把
+適當的值寫入 ``/sys/module/damon_reclaim/parameters/<parameter>`` 文件。
+
+下面是每個參數的描述。
+
+enabled
+-------
+
+啓用或禁用DAMON_RECLAIM。
+
+你可以通過把這個參數的值設置爲 ``Y`` 來啓用DAMON_RCLAIM,把它設置爲 ``N`` 可以禁用
+DAMON_RECLAIM。注意,由於基於水位的激活條件,DAMON_RECLAIM不能進行真正的監測和回收。
+這一點請參考下面關於水位參數的描述。
+
+min_age
+-------
+
+識別冷內存區域的時間閾值,單位是微秒。
+
+如果一個內存區域在這個時間或更長的時間內沒有被訪問,DAMON_RECLAIM會將該區域識別爲冷的,
+並回收它。
+
+默認爲120秒。
+
+quota_ms
+--------
+
+回收的時間限制,以毫秒爲單位。
+
+DAMON_RECLAIM 試圖在一個時間窗口(quota_reset_interval_ms)內只使用到這個時間,以
+嘗試回收冷頁。這可以用來限制DAMON_RECLAIM的CPU消耗。如果該值爲零,則該限制被禁用。
+
+默認爲10ms。
+
+quota_sz
+--------
+
+回收的內存大小限制,單位爲字節。
+
+DAMON_RECLAIM 收取在一個時間窗口(quota_reset_interval_ms)內試圖回收的內存量,並
+使其不超過這個限制。這可以用來限制CPU和IO的消耗。如果該值爲零,則限制被禁用。
+
+默認情況下是128 MiB。
+
+quota_reset_interval_ms
+-----------------------
+
+時間/大小配額收取重置間隔,單位爲毫秒。
+
+時間(quota_ms)和大小(quota_sz)的配額的目標重置間隔。也就是說,DAMON_RECLAIM在
+嘗試回收‘不’超過quota_ms毫秒或quota_sz字節的內存。
+
+默認爲1秒。
+
+wmarks_interval
+---------------
+
+當DAMON_RECLAIM被啓用但由於其水位規則而不活躍時,在檢查水位之前的最小等待時間。
+
+wmarks_high
+-----------
+
+高水位的可用內存率(每千字節)。
+
+如果系統的可用內存(以每千字節爲單位)高於這個數值,DAMON_RECLAIM就會變得不活躍,所以
+它什麼也不做,只是定期檢查水位。
+
+wmarks_mid
+----------
+
+中間水位的可用內存率(每千字節)。
+
+如果系統的空閒內存(以每千字節爲單位)在這個和低水位線之間,DAMON_RECLAIM就會被激活,
+因此開始監測和回收。
+
+wmarks_low
+----------
+
+低水位的可用內存率(每千字節)。
+
+如果系統的空閒內存(以每千字節爲單位)低於這個數值,DAMON_RECLAIM就會變得不活躍,所以
+它除了定期檢查水位外什麼都不做。在這種情況下,系統會退回到基於LRU列表的頁面粒度回收邏輯。
+
+sample_interval
+---------------
+
+監測的採樣間隔,單位是微秒。
+
+DAMON用於監測冷內存的採樣間隔。更多細節請參考DAMON文檔 (:doc:`usage`) 。
+
+aggr_interval
+-------------
+
+監測的聚集間隔,單位是微秒。
+
+DAMON對冷內存監測的聚集間隔。更多細節請參考DAMON文檔 (:doc:`usage`)。
+
+min_nr_regions
+--------------
+
+監測區域的最小數量。
+
+DAMON用於冷內存監測的最小監測區域數。這可以用來設置監測質量的下限。但是,設
+置的太高可能會導致監測開銷的增加。更多細節請參考DAMON文檔 (:doc:`usage`) 。
+
+max_nr_regions
+--------------
+
+監測區域的最大數量。
+
+DAMON用於冷內存監測的最大監測區域數。這可以用來設置監測開銷的上限值。但是,
+設置得太低可能會導致監測質量不好。更多細節請參考DAMON文檔 (:doc:`usage`) 。
+
+monitor_region_start
+--------------------
+
+目標內存區域的物理地址起點。
+
+DAMON_RECLAIM將對其進行工作的內存區域的起始物理地址。也就是說,DAMON_RECLAIM
+將在這個區域中找到冷的內存區域並進行回收。默認情況下,該區域使用最大系統內存區。
+
+monitor_region_end
+------------------
+
+目標內存區域的結束物理地址。
+
+DAMON_RECLAIM將對其進行工作的內存區域的末端物理地址。也就是說,DAMON_RECLAIM將
+在這個區域內找到冷的內存區域並進行回收。默認情況下,該區域使用最大系統內存區。
+
+kdamond_pid
+-----------
+
+DAMON線程的PID。
+
+如果DAMON_RECLAIM被啓用,這將成爲工作線程的PID。否則,爲-1。
+
+nr_reclaim_tried_regions
+------------------------
+
+試圖通過DAMON_RECLAIM回收的內存區域的數量。
+
+bytes_reclaim_tried_regions
+---------------------------
+
+試圖通過DAMON_RECLAIM回收的內存區域的總字節數。
+
+nr_reclaimed_regions
+--------------------
+
+通過DAMON_RECLAIM成功回收的內存區域的數量。
+
+bytes_reclaimed_regions
+-----------------------
+
+通過DAMON_RECLAIM成功回收的內存區域的總字節數。
+
+nr_quota_exceeds
+----------------
+
+超過時間/空間配額限制的次數。
+
+例子
+====
+
+下面的運行示例命令使DAMON_RECLAIM找到30秒或更長時間沒有訪問的內存區域並“回收”?
+爲了避免DAMON_RECLAIM在分頁操作中消耗過多的CPU時間,回收被限制在每秒1GiB以內。
+它還要求DAMON_RECLAIM在系統的可用內存率超過50%時不做任何事情,但如果它低於40%時
+就開始真正的工作。如果DAMON_RECLAIM沒有取得進展,因此空閒內存率低於20%,它會要求
+DAMON_RECLAIM再次什麼都不做,這樣我們就可以退回到基於LRU列表的頁面粒度回收了::
+
+    # cd /sys/module/damon_reclaim/parameters
+    # echo 30000000 > min_age
+    # echo $((1 * 1024 * 1024 * 1024)) > quota_sz
+    # echo 1000 > quota_reset_interval_ms
+    # echo 500 > wmarks_high
+    # echo 400 > wmarks_mid
+    # echo 200 > wmarks_low
+    # echo Y > enabled
+
+.. [1] https://research.google/pubs/pub48551/
+.. [2] https://lwn.net/Articles/787611/
+.. [3] https://www.kernel.org/doc/html/latest/mm/free_page_reporting.html
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst
new file mode 100644
index 000000000000..9b8be5addd45
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/start.rst
@@ -0,0 +1,126 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/start.rst
+
+:翻譯:
+
+ 司延騰 Yanteng Si <siyanteng@loongson.cn>
+
+:校譯:
+
+========
+入門指南
+========
+
+本文通過演示DAMON的默認用戶空間工具,簡要地介紹瞭如何使用DAMON。請注意,爲了簡潔
+起見,本文檔只描述了它的部分功能。更多細節請參考該工具的使用文檔。
+`doc <https://github.com/awslabs/damo/blob/next/USAGE.md>`_ .
+
+
+前提條件
+========
+
+內核
+----
+
+首先,你要確保你當前系統中跑的內核構建時選定了這個功能選項 ``CONFIG_DAMON_*=y``.
+
+
+用戶空間工具
+------------
+
+在演示中,我們將使用DAMON的默認用戶空間工具,稱爲DAMON Operator(DAMO)。它可以在
+https://github.com/awslabs/damo找到。下面的例子假設DAMO在你的$PATH上。當然,但
+這並不是強制性的。
+
+因爲DAMO使用了DAMON的sysfs接口(詳情請參考:doc:`usage`),你應該確保
+:doc:`sysfs </filesystems/sysfs>` 被掛載。
+
+記錄數據訪問模式
+================
+
+下面的命令記錄了一個程序的內存訪問模式,並將監測結果保存到文件中。 ::
+
+    $ git clone https://github.com/sjp38/masim
+    $ cd masim; make; ./masim ./configs/zigzag.cfg &
+    $ sudo damo record -o damon.data $(pidof masim)
+
+命令的前兩行下載了一個人工內存訪問生成器程序並在後臺運行。生成器將重複地逐一訪問兩個
+100 MiB大小的內存區域。你可以用你的真實工作負載來代替它。最後一行要求 ``damo`` 將
+訪問模式記錄在 ``damon.data`` 文件中。
+
+
+將記錄的模式可視化
+==================
+
+你可以在heatmap中直觀地看到這種模式,顯示哪個內存區域(X軸)何時被訪問(Y軸)以及訪
+問的頻率(數字)。::
+
+    $ sudo damo report heats --heatmap stdout
+    22222222222222222222222222222222222222211111111111111111111111111111111111111100
+    44444444444444444444444444444444444444434444444444444444444444444444444444443200
+    44444444444444444444444444444444444444433444444444444444444444444444444444444200
+    33333333333333333333333333333333333333344555555555555555555555555555555555555200
+    33333333333333333333333333333333333344444444444444444444444444444444444444444200
+    22222222222222222222222222222222222223355555555555555555555555555555555555555200
+    00000000000000000000000000000000000000288888888888888888888888888888888888888400
+    00000000000000000000000000000000000000288888888888888888888888888888888888888400
+    33333333333333333333333333333333333333355555555555555555555555555555555555555200
+    88888888888888888888888888888888888888600000000000000000000000000000000000000000
+    88888888888888888888888888888888888888600000000000000000000000000000000000000000
+    33333333333333333333333333333333333333444444444444444444444444444444444444443200
+    00000000000000000000000000000000000000288888888888888888888888888888888888888400
+    [...]
+    # access_frequency:  0  1  2  3  4  5  6  7  8  9
+    # x-axis: space (139728247021568-139728453431248: 196.848 MiB)
+    # y-axis: time (15256597248362-15326899978162: 1 m 10.303 s)
+    # resolution: 80x40 (2.461 MiB and 1.758 s for each character)
+
+你也可以直觀地看到工作集的大小分佈,按大小排序。::
+
+    $ sudo damo report wss --range 0 101 10
+    # <percentile> <wss>
+    # target_id     18446632103789443072
+    # avr:  107.708 MiB
+      0             0 B |                                                           |
+     10      95.328 MiB |****************************                               |
+     20      95.332 MiB |****************************                               |
+     30      95.340 MiB |****************************                               |
+     40      95.387 MiB |****************************                               |
+     50      95.387 MiB |****************************                               |
+     60      95.398 MiB |****************************                               |
+     70      95.398 MiB |****************************                               |
+     80      95.504 MiB |****************************                               |
+     90     190.703 MiB |*********************************************************  |
+    100     196.875 MiB |***********************************************************|
+
+在上述命令中使用 ``--sortby`` 選項,可以顯示工作集的大小是如何按時間順序變化的。::
+
+    $ sudo damo report wss --range 0 101 10 --sortby time
+    # <percentile> <wss>
+    # target_id     18446632103789443072
+    # avr:  107.708 MiB
+      0       3.051 MiB |                                                           |
+     10     190.703 MiB |***********************************************************|
+     20      95.336 MiB |*****************************                              |
+     30      95.328 MiB |*****************************                              |
+     40      95.387 MiB |*****************************                              |
+     50      95.332 MiB |*****************************                              |
+     60      95.320 MiB |*****************************                              |
+     70      95.398 MiB |*****************************                              |
+     80      95.398 MiB |*****************************                              |
+     90      95.340 MiB |*****************************                              |
+    100      95.398 MiB |*****************************                              |
+
+
+數據訪問模式感知的內存管理
+==========================
+
+以下三個命令使每一個大小>=4K的內存區域在你的工作負載中沒有被訪問>=60秒,就會被換掉。 ::
+
+    $ echo "#min-size max-size min-acc max-acc min-age max-age action" > test_scheme
+    $ echo "4K        max      0       0       60s     max     pageout" >> test_scheme
+    $ damo schemes -c test_scheme <pid of your workload>
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst b/Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst
new file mode 100644
index 000000000000..ac1af36bb17d
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/damon/usage.rst
@@ -0,0 +1,593 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/damon/usage.rst
+
+:翻譯:
+
+ 司延騰 Yanteng Si <siyanteng@loongson.cn>
+
+:校譯:
+
+========
+詳細用法
+========
+
+DAMON 爲不同的用戶提供了下面這些接口。
+
+- *DAMON用戶空間工具。*
+  `這 <https://github.com/awslabs/damo>`_ 爲有這特權的人, 如系統管理員,希望有一個剛好
+  可以工作的人性化界面。
+  使用它,用戶可以以人性化的方式使用DAMON的主要功能。不過,它可能不會爲特殊情況進行高度調整。
+  它同時支持虛擬和物理地址空間的監測。更多細節,請參考它的 `使用文檔
+  <https://github.com/awslabs/damo/blob/next/USAGE.md>`_。
+- *sysfs接口。*
+  :ref:`這 <sysfs_interface>` 是爲那些希望更高級的使用DAMON的特權用戶空間程序員準備的。
+  使用它,用戶可以通過讀取和寫入特殊的sysfs文件來使用DAMON的主要功能。因此,你可以編寫和使
+  用你個性化的DAMON sysfs包裝程序,代替你讀/寫sysfs文件。  `DAMON用戶空間工具
+  <https://github.com/awslabs/damo>`_ 就是這種程序的一個例子  它同時支持虛擬和物理地址
+  空間的監測。注意,這個界面只提供簡單的監測結果 :ref:`統計 <damos_stats>`。對於詳細的監測
+  結果,DAMON提供了一個:ref:`跟蹤點 <tracepoint>`。
+- *debugfs interface.*
+  :ref:`這 <debugfs_interface>` 幾乎與:ref:`sysfs interface <sysfs_interface>` 接
+  口相同。這將在下一個LTS內核發佈後被移除,所以用戶應該轉移到
+  :ref:`sysfs interface <sysfs_interface>`。
+- *內核空間編程接口。*
+  :doc:`這 </mm/damon/api>` 這是爲內核空間程序員準備的。使用它,用戶可以通過爲你編寫內
+  核空間的DAMON應用程序,最靈活有效地利用DAMON的每一個功能。你甚至可以爲各種地址空間擴展DAMON。
+  詳細情況請參考接口 :doc:`文件 </mm/damon/api>`。
+
+sysfs接口
+=========
+DAMON的sysfs接口是在定義 ``CONFIG_DAMON_SYSFS`` 時建立的。它在其sysfs目錄下創建多
+個目錄和文件, ``<sysfs>/kernel/mm/damon/`` 。你可以通過對該目錄下的文件進行寫入和
+讀取來控制DAMON。
+
+對於一個簡短的例子,用戶可以監測一個給定工作負載的虛擬地址空間,如下所示::
+
+    # cd /sys/kernel/mm/damon/admin/
+    # echo 1 > kdamonds/nr_kdamonds && echo 1 > kdamonds/0/contexts/nr_contexts
+    # echo vaddr > kdamonds/0/contexts/0/operations
+    # echo 1 > kdamonds/0/contexts/0/targets/nr_targets
+    # echo $(pidof <workload>) > kdamonds/0/contexts/0/targets/0/pid_target
+    # echo on > kdamonds/0/state
+
+文件層次結構
+------------
+
+DAMON sysfs接口的文件層次結構如下圖所示。在下圖中,父子關係用縮進表示,每個目錄有
+``/`` 後綴,每個目錄中的文件用逗號(",")分開。 ::
+
+    /sys/kernel/mm/damon/admin
+    │ kdamonds/nr_kdamonds
+    │ │ 0/state,pid
+    │ │ │ contexts/nr_contexts
+    │ │ │ │ 0/operations
+    │ │ │ │ │ monitoring_attrs/
+    │ │ │ │ │ │ intervals/sample_us,aggr_us,update_us
+    │ │ │ │ │ │ nr_regions/min,max
+    │ │ │ │ │ targets/nr_targets
+    │ │ │ │ │ │ 0/pid_target
+    │ │ │ │ │ │ │ regions/nr_regions
+    │ │ │ │ │ │ │ │ 0/start,end
+    │ │ │ │ │ │ │ │ ...
+    │ │ │ │ │ │ ...
+    │ │ │ │ │ schemes/nr_schemes
+    │ │ │ │ │ │ 0/action
+    │ │ │ │ │ │ │ access_pattern/
+    │ │ │ │ │ │ │ │ sz/min,max
+    │ │ │ │ │ │ │ │ nr_accesses/min,max
+    │ │ │ │ │ │ │ │ age/min,max
+    │ │ │ │ │ │ │ quotas/ms,bytes,reset_interval_ms
+    │ │ │ │ │ │ │ │ weights/sz_permil,nr_accesses_permil,age_permil
+    │ │ │ │ │ │ │ watermarks/metric,interval_us,high,mid,low
+    │ │ │ │ │ │ │ stats/nr_tried,sz_tried,nr_applied,sz_applied,qt_exceeds
+    │ │ │ │ │ │ │ tried_regions/
+    │ │ │ │ │ │ │ │ 0/start,end,nr_accesses,age
+    │ │ │ │ │ │ │ │ ...
+    │ │ │ │ │ │ ...
+    │ │ │ │ ...
+    │ │ ...
+
+根
+--
+
+DAMON sysfs接口的根是 ``<sysfs>/kernel/mm/damon/`` ,它有一個名爲 ``admin`` 的
+目錄。該目錄包含特權用戶空間程序控制DAMON的文件。擁有根權限的用戶空間工具或deamons可以
+使用這個目錄。
+
+kdamonds/
+---------
+
+與監測相關的信息包括請求規格和結果被稱爲DAMON上下文。DAMON用一個叫做kdamond的內核線程
+執行每個上下文,多個kdamonds可以並行運行。
+
+在 ``admin`` 目錄下,有一個目錄,即``kdamonds``,它有控制kdamonds的文件存在。在開始
+時,這個目錄只有一個文件,``nr_kdamonds``。向該文件寫入一個數字(``N``),就會創建名爲
+``0`` 到 ``N-1`` 的子目錄數量。每個目錄代表每個kdamond。
+
+kdamonds/<N>/
+-------------
+
+在每個kdamond目錄中,存在兩個文件(``state`` 和 ``pid`` )和一個目錄( ``contexts`` )。
+
+讀取 ``state`` 時,如果kdamond當前正在運行,則返回 ``on`` ,如果沒有運行則返回 ``off`` 。
+寫入 ``on`` 或 ``off`` 使kdamond處於狀態。向 ``state`` 文件寫 ``update_schemes_stats`` ,
+更新kdamond的每個基於DAMON的操作方案的統計文件的內容。關於統計信息的細節,請參考
+:ref:`stats section <sysfs_schemes_stats>`. 將 ``update_schemes_tried_regions`` 寫到
+``state`` 文件,爲kdamond的每個基於DAMON的操作方案,更新基於DAMON的操作方案動作的嘗試區域目錄。
+將`clear_schemes_tried_regions`寫入`state`文件,清除kdamond的每個基於DAMON的操作方案的動作
+嘗試區域目錄。 關於基於DAMON的操作方案動作嘗試區域目錄的細節,請參考:ref:tried_regions 部分
+<sysfs_schemes_tried_regions>`。
+
+如果狀態爲 ``on``,讀取 ``pid`` 顯示kdamond線程的pid。
+
+``contexts`` 目錄包含控制這個kdamond要執行的監測上下文的文件。
+
+kdamonds/<N>/contexts/
+----------------------
+
+在開始時,這個目錄只有一個文件,即 ``nr_contexts`` 。向該文件寫入一個數字( ``N`` ),就會創
+建名爲``0`` 到 ``N-1`` 的子目錄數量。每個目錄代表每個監測背景。目前,每個kdamond只支持
+一個上下文,所以只有 ``0`` 或 ``1`` 可以被寫入文件。
+
+contexts/<N>/
+-------------
+
+在每個上下文目錄中,存在一個文件(``operations``)和三個目錄(``monitoring_attrs``,
+``targets``, 和 ``schemes``)。
+
+DAMON支持多種類型的監測操作,包括對虛擬地址空間和物理地址空間的監測。你可以通過向文件
+中寫入以下關鍵詞之一,並從文件中讀取,來設置和獲取DAMON將爲上下文使用何種類型的監測操作。
+
+ - vaddr: 監測特定進程的虛擬地址空間
+ - paddr: 監視系統的物理地址空間
+
+contexts/<N>/monitoring_attrs/
+------------------------------
+
+用於指定監測屬性的文件,包括所需的監測質量和效率,都在 ``monitoring_attrs`` 目錄中。
+具體來說,這個目錄下有兩個目錄,即 ``intervals`` 和 ``nr_regions`` 。
+
+在 ``intervals`` 目錄下,存在DAMON的採樣間隔(``sample_us``)、聚集間隔(``aggr_us``)
+和更新間隔(``update_us``)三個文件。你可以通過寫入和讀出這些文件來設置和獲取微秒級的值。
+
+在 ``nr_regions`` 目錄下,有兩個文件分別用於DAMON監測區域的下限和上限(``min`` 和 ``max`` ),
+這兩個文件控制着監測的開銷。你可以通過向這些文件的寫入和讀出來設置和獲取這些值。
+
+關於間隔和監測區域範圍的更多細節,請參考設計文件 (:doc:`/mm/damon/design`)。
+
+contexts/<N>/targets/
+---------------------
+
+在開始時,這個目錄只有一個文件 ``nr_targets`` 。向該文件寫入一個數字(``N``),就可以創建
+名爲 ``0`` 到 ``N-1`` 的子目錄的數量。每個目錄代表每個監測目標。
+
+targets/<N>/
+------------
+
+在每個目標目錄中,存在一個文件(``pid_target``)和一個目錄(``regions``)。
+
+如果你把 ``vaddr`` 寫到 ``contexts/<N>/operations`` 中,每個目標應該是一個進程。你
+可以通過將進程的pid寫到 ``pid_target`` 文件中來指定DAMON的進程。
+
+targets/<N>/regions
+-------------------
+
+當使用 ``vaddr`` 監測操作集時( ``vaddr`` 被寫入 ``contexts/<N>/operations`` 文
+件),DAMON自動設置和更新監測目標區域,這樣就可以覆蓋目標進程的整個內存映射。然而,用戶可
+能希望將初始監測區域設置爲特定的地址範圍。
+
+相反,當使用 ``paddr`` 監測操作集時,DAMON不會自動設置和更新監測目標區域( ``paddr``
+被寫入 ``contexts/<N>/operations`` 中)。因此,在這種情況下,用戶應該自己設置監測目標
+區域。
+
+在這種情況下,用戶可以按照自己的意願明確設置初始監測目標區域,將適當的值寫入該目錄下的文件。
+
+開始時,這個目錄只有一個文件, ``nr_regions`` 。向該文件寫入一個數字(``N``),就可以創
+建名爲 ``0`` 到  ``N-1`` 的子目錄。每個目錄代表每個初始監測目標區域。
+
+regions/<N>/
+------------
+
+在每個區域目錄中,你會發現兩個文件( ``start``  和  ``end`` )。你可以通過向文件寫入
+和從文件中讀出,分別設置和獲得初始監測目標區域的起始和結束地址。
+
+每個區域不應該與其他區域重疊。 目錄“N”的“結束”應等於或小於目錄“N+1”的“開始”。
+
+contexts/<N>/schemes/
+---------------------
+
+對於一版的基於DAMON的數據訪問感知的內存管理優化,用戶通常希望系統對特定訪問模式的內存區
+域應用內存管理操作。DAMON從用戶那裏接收這種形式化的操作方案,並將這些方案應用於目標內存
+區域。用戶可以通過讀取和寫入這個目錄下的文件來獲得和設置這些方案。
+
+在開始時,這個目錄只有一個文件,``nr_schemes``。向該文件寫入一個數字(``N``),就可以
+創建名爲``0``到``N-1``的子目錄的數量。每個目錄代表每個基於DAMON的操作方案。
+
+schemes/<N>/
+------------
+
+在每個方案目錄中,存在五個目錄(``access_pattern``、``quotas``、``watermarks``、
+``stats`` 和 ``tried_regions``)和一個文件(``action``)。
+
+``action`` 文件用於設置和獲取你想應用於具有特定訪問模式的內存區域的動作。可以寫入文件
+和從文件中讀取的關鍵詞及其含義如下。
+
+ - ``willneed``: 對有 ``MADV_WILLNEED`` 的區域調用 ``madvise()`` 。
+ - ``cold``: 對具有 ``MADV_COLD`` 的區域調用 ``madvise()`` 。
+ - ``pageout``: 爲具有 ``MADV_PAGEOUT`` 的區域調用 ``madvise()`` 。
+ - ``hugepage``: 爲帶有 ``MADV_HUGEPAGE`` 的區域調用 ``madvise()`` 。
+ - ``nohugepage``: 爲帶有 ``MADV_NOHUGEPAGE`` 的區域調用 ``madvise()``。
+ - ``lru_prio``: 在其LRU列表上對區域進行優先排序。
+ - ``lru_deprio``: 對區域的LRU列表進行降低優先處理。
+ - ``stat``: 什麼都不做,只計算統計數據
+
+schemes/<N>/access_pattern/
+---------------------------
+
+每個基於DAMON的操作方案的目標訪問模式由三個範圍構成,包括以字節爲單位的區域大小、每個
+聚合區間的監測訪問次數和區域年齡的聚合區間數。
+
+在 ``access_pattern`` 目錄下,存在三個目錄( ``sz``, ``nr_accesses``, 和 ``age`` ),
+每個目錄有兩個文件(``min`` 和 ``max`` )。你可以通過向  ``sz``, ``nr_accesses``, 和
+``age``  目錄下的 ``min`` 和 ``max`` 文件分別寫入和讀取來設置和獲取給定方案的訪問模式。
+
+schemes/<N>/quotas/
+-------------------
+
+每個 ``動作`` 的最佳 ``目標訪問模式`` 取決於工作負載,所以不容易找到。更糟糕的是,將某些動作
+的方案設置得過於激進會造成嚴重的開銷。爲了避免這種開銷,用戶可以爲每個方案限制時間和大小配額。
+具體來說,用戶可以要求DAMON儘量只使用特定的時間(``時間配額``)來應用動作,並且在給定的時間間
+隔(``重置間隔``)內,只對具有目標訪問模式的內存區域應用動作,而不使用特定數量(``大小配額``)。
+
+當預計超過配額限制時,DAMON會根據 ``目標訪問模式`` 的大小、訪問頻率和年齡,對找到的內存區域
+進行優先排序。爲了進行個性化的優先排序,用戶可以爲這三個屬性設置權重。
+
+在 ``quotas`` 目錄下,存在三個文件(``ms``, ``bytes``, ``reset_interval_ms``)和一個
+目錄(``weights``),其中有三個文件(``sz_permil``, ``nr_accesses_permil``, 和
+``age_permil``)。
+
+你可以設置以毫秒爲單位的 ``時間配額`` ,以字節爲單位的 ``大小配額`` ,以及以毫秒爲單位的 ``重
+置間隔`` ,分別向這三個文件寫入數值。你還可以通過向 ``weights`` 目錄下的三個文件寫入數值來設
+置大小、訪問頻率和年齡的優先權,單位爲千分之一。
+
+schemes/<N>/watermarks/
+-----------------------
+
+爲了便於根據系統狀態激活和停用每個方案,DAMON提供了一個稱爲水位的功能。該功能接收五個值,稱爲
+``度量`` 、``間隔`` 、``高`` 、``中`` 、``低`` 。``度量值`` 是指可以測量的系統度量值,如
+自由內存比率。如果系統的度量值 ``高`` 於memoent的高值或 ``低`` 於低值,則該方案被停用。如果
+該值低於 ``中`` ,則該方案被激活。
+
+在水位目錄下,存在五個文件(``metric``, ``interval_us``,``high``, ``mid``, and ``low``)
+用於設置每個值。你可以通過向這些文件的寫入來分別設置和獲取這五個值。
+
+可以寫入 ``metric`` 文件的關鍵詞和含義如下。
+
+ - none: 忽略水位
+ - free_mem_rate: 系統的自由內存率(千分比)。
+
+``interval`` 應以微秒爲單位寫入。
+
+schemes/<N>/stats/
+------------------
+
+DAMON統計每個方案被嘗試應用的區域的總數量和字節數,每個方案被成功應用的區域的兩個數字,以及
+超過配額限制的總數量。這些統計數據可用於在線分析或調整方案。
+
+可以通過讀取 ``stats`` 目錄下的文件(``nr_tried``, ``sz_tried``, ``nr_applied``,
+``sz_applied``, 和 ``qt_exceeds``))分別檢索這些統計數據。這些文件不是實時更新的,所以
+你應該要求DAMON sysfs接口通過在相關的 ``kdamonds/<N>/state`` 文件中寫入一個特殊的關鍵字
+``update_schemes_stats`` 來更新統計信息的文件內容。
+
+schemes/<N>/tried_regions/
+--------------------------
+
+當一個特殊的關鍵字 ``update_schemes_tried_regions`` 被寫入相關的 ``kdamonds/<N>/state``
+文件時,DAMON會在這個目錄下創建從 ``0`` 開始命名的整數目錄。每個目錄包含的文件暴露了關於每個
+內存區域的詳細信息,在下一個 :ref:`聚集區間 <sysfs_monitoring_attrs>`,相應的方案的 ``動作``
+已經嘗試在這個目錄下應用。這些信息包括地址範圍、``nr_accesses`` 以及區域的 ``年齡`` 。
+
+當另一個特殊的關鍵字 ``clear_schemes_tried_regions`` 被寫入相關的 ``kdamonds/<N>/state``
+文件時,這些目錄將被刪除。
+
+tried_regions/<N>/
+------------------
+
+在每個區域目錄中,你會發現四個文件(``start``, ``end``, ``nr_accesses``, and ``age``)。
+讀取這些文件將顯示相應的基於DAMON的操作方案 ``動作`` 試圖應用的區域的開始和結束地址、``nr_accesses``
+和 ``年齡`` 。
+
+用例
+~~~~
+
+下面的命令應用了一個方案:”如果一個大小爲[4KiB, 8KiB]的內存區域在[10, 20]的聚合時間間隔內
+顯示出每一個聚合時間間隔[0, 5]的訪問量,請分頁該區域。對於分頁,每秒最多隻能使用10ms,而且每
+秒分頁不能超過1GiB。在這一限制下,首先分頁出具有較長年齡的內存區域。另外,每5秒鐘檢查一次系統
+的可用內存率,當可用內存率低於50%時開始監測和分頁,但如果可用內存率大於60%,或低於30%,則停
+止監測。“ ::
+
+    # cd <sysfs>/kernel/mm/damon/admin
+    # # populate directories
+    # echo 1 > kdamonds/nr_kdamonds; echo 1 > kdamonds/0/contexts/nr_contexts;
+    # echo 1 > kdamonds/0/contexts/0/schemes/nr_schemes
+    # cd kdamonds/0/contexts/0/schemes/0
+    # # set the basic access pattern and the action
+    # echo 4096 > access_pattern/sz/min
+    # echo 8192 > access_pattern/sz/max
+    # echo 0 > access_pattern/nr_accesses/min
+    # echo 5 > access_pattern/nr_accesses/max
+    # echo 10 > access_pattern/age/min
+    # echo 20 > access_pattern/age/max
+    # echo pageout > action
+    # # set quotas
+    # echo 10 > quotas/ms
+    # echo $((1024*1024*1024)) > quotas/bytes
+    # echo 1000 > quotas/reset_interval_ms
+    # # set watermark
+    # echo free_mem_rate > watermarks/metric
+    # echo 5000000 > watermarks/interval_us
+    # echo 600 > watermarks/high
+    # echo 500 > watermarks/mid
+    # echo 300 > watermarks/low
+
+請注意,我們強烈建議使用用戶空間的工具,如 `damo <https://github.com/awslabs/damo>`_ ,
+而不是像上面那樣手動讀寫文件。以上只是一個例子。
+
+debugfs接口
+===========
+
+.. note::
+
+  DAMON debugfs接口將在下一個LTS內核發佈後被移除,所以用戶應該轉移到
+  :ref:`sysfs接口<sysfs_interface>`。
+
+DAMON導出了八個文件, ``attrs``, ``target_ids``, ``init_regions``,
+``schemes``, ``monitor_on``, ``kdamond_pid``, ``mk_contexts`` 和
+``rm_contexts`` under its debugfs directory, ``<debugfs>/damon/``.
+
+
+屬性
+----
+
+用戶可以通過讀取和寫入 ``attrs`` 文件獲得和設置 ``採樣間隔`` 、 ``聚集間隔`` 、 ``更新間隔``
+以及監測目標區域的最小/最大數量。要詳細瞭解監測屬性,請參考 `:doc:/mm/damon/design` 。例如,
+下面的命令將這些值設置爲5ms、100ms、1000ms、10和1000,然後再次檢查::
+
+    # cd <debugfs>/damon
+    # echo 5000 100000 1000000 10 1000 > attrs
+    # cat attrs
+    5000 100000 1000000 10 1000
+
+
+目標ID
+------
+
+一些類型的地址空間支持多個監測目標。例如,虛擬內存地址空間的監測可以有多個進程作爲監測目標。用戶
+可以通過寫入目標的相關id值來設置目標,並通過讀取 ``target_ids`` 文件來獲得當前目標的id。在監
+測虛擬地址空間的情況下,這些值應該是監測目標進程的pid。例如,下面的命令將pid爲42和4242的進程設
+爲監測目標,並再次檢查::
+
+    # cd <debugfs>/damon
+    # echo 42 4242 > target_ids
+    # cat target_ids
+    42 4242
+
+用戶還可以通過在文件中寫入一個特殊的關鍵字 "paddr\n" 來監測系統的物理內存地址空間。因爲物理地
+址空間監測不支持多個目標,讀取文件會顯示一個假值,即 ``42`` ,如下圖所示::
+
+    # cd <debugfs>/damon
+    # echo paddr > target_ids
+    # cat target_ids
+    42
+
+請注意,設置目標ID並不啓動監測。
+
+
+初始監測目標區域
+----------------
+
+在虛擬地址空間監測的情況下,DAMON自動設置和更新監測的目標區域,這樣就可以覆蓋目標進程的整個
+內存映射。然而,用戶可能希望將監測區域限制在特定的地址範圍內,如堆、棧或特定的文件映射區域。
+或者,一些用戶可以知道他們工作負載的初始訪問模式,因此希望爲“自適應區域調整”設置最佳初始區域。
+
+相比之下,DAMON在物理內存監測的情況下不會自動設置和更新監測目標區域。因此,用戶應該自己設置
+監測目標區域。
+
+在這種情況下,用戶可以通過在 ``init_regions`` 文件中寫入適當的值,明確地設置他們想要的初
+始監測目標區域。輸入應該是一個由三個整數組成的隊列,用空格隔開,代表一個區域的形式如下::
+
+    <target idx> <start address> <end address>
+
+目標idx應該是 ``target_ids`` 文件中目標的索引,從 ``0`` 開始,區域應該按照地址順序傳遞。
+例如,下面的命令將設置幾個地址範圍, ``1-100`` 和 ``100-200`` 作爲pid 42的初始監測目標
+區域,這是 ``target_ids`` 中的第一個(索引 ``0`` ),另外幾個地址範圍, ``20-40`` 和
+``50-100`` 作爲pid 4242的地址,這是 ``target_ids`` 中的第二個(索引 ``1`` )::
+
+    # cd <debugfs>/damon
+    # cat target_ids
+    42 4242
+    # echo "0   1       100 \
+            0   100     200 \
+            1   20      40  \
+            1   50      100" > init_regions
+
+請注意,這只是設置了初始的監測目標區域。在虛擬內存監測的情況下,DAMON會在一個 ``更新間隔``
+後自動更新區域的邊界。因此,在這種情況下,如果用戶不希望更新的話,應該把 ``更新間隔`` 設
+置得足夠大。
+
+
+方案
+----
+
+對於通常的基於DAMON的數據訪問感知的內存管理優化,用戶只是希望系統對特定訪問模式的內存區域應用內
+存管理操作。DAMON從用戶那裏接收這種形式化的操作方案,並將這些方案應用到目標進程中。
+
+用戶可以通過讀取和寫入 ``scheme`` debugfs文件來獲得和設置這些方案。讀取該文件還可以顯示每個
+方案的統計數據。在文件中,每一個方案都應該在每一行中以下列形式表示出來::
+
+    <target access pattern> <action> <quota> <watermarks>
+
+你可以通過簡單地在文件中寫入一個空字符串來禁用方案。
+
+目標訪問模式
+~~~~~~~~~~~~
+
+``<目標訪問模式>`` 是由三個範圍構成的,形式如下::
+
+    min-size max-size min-acc max-acc min-age max-age
+
+具體來說,區域大小的字節數( `min-size` 和 `max-size` ),訪問頻率的每聚合區間的監測訪問次
+數( `min-acc` 和 `max-acc` ),區域年齡的聚合區間數( `min-age` 和 `max-age` )都被指定。
+請注意,這些範圍是封閉區間。
+
+動作
+~~~~
+
+``<action>`` 是一個預定義的內存管理動作的整數,DAMON將應用於具有目標訪問模式的區域。支持
+的數字和它們的含義如下::
+
+ - 0: Call ``madvise()`` for the region with ``MADV_WILLNEED``
+ - 1: Call ``madvise()`` for the region with ``MADV_COLD``
+ - 2: Call ``madvise()`` for the region with ``MADV_PAGEOUT``
+ - 3: Call ``madvise()`` for the region with ``MADV_HUGEPAGE``
+ - 4: Call ``madvise()`` for the region with ``MADV_NOHUGEPAGE``
+ - 5: Do nothing but count the statistics
+
+配額
+~~~~
+
+每個 ``動作`` 的最佳 ``目標訪問模式`` 取決於工作負載,所以不容易找到。更糟糕的是,將某個
+動作的方案設置得過於激進會導致嚴重的開銷。爲了避免這種開銷,用戶可以通過下面表格中的 ``<quota>``
+來限制方案的時間和大小配額::
+
+    <ms> <sz> <reset interval> <priority weights>
+
+這使得DAMON在 ``<reset interval>`` 毫秒內,儘量只用 ``<ms>`` 毫秒的時間對 ``目標訪
+問模式`` 的內存區域應用動作,並在 ``<reset interval>`` 內只對最多<sz>字節的內存區域應
+用動作。將 ``<ms>`` 和 ``<sz>`` 都設置爲零,可以禁用配額限制。
+
+當預計超過配額限制時,DAMON會根據 ``目標訪問模式`` 的大小、訪問頻率和年齡,對發現的內存
+區域進行優先排序。爲了實現個性化的優先級,用戶可以在 ``<優先級權重>`` 中設置這三個屬性的
+權重,具體形式如下::
+
+    <size weight> <access frequency weight> <age weight>
+
+水位
+~~~~
+
+有些方案需要根據系統特定指標的當前值來運行,如自由內存比率。對於這種情況,用戶可以爲該條
+件指定水位。::
+
+    <metric> <check interval> <high mark> <middle mark> <low mark>
+
+``<metric>`` 是一個預定義的整數,用於要檢查的度量。支持的數字和它們的含義如下。
+
+ - 0: 忽視水位
+ - 1: 系統空閒內存率 (千分比)
+
+每隔 ``<檢查間隔>`` 微秒檢查一次公制的值。
+
+如果該值高於 ``<高標>`` 或低於 ``<低標>`` ,該方案被停用。如果該值低於 ``<中標>`` ,
+該方案將被激活。
+
+統計數據
+~~~~~~~~
+
+它還統計每個方案被嘗試應用的區域的總數量和字節數,每個方案被成功應用的區域的兩個數量,以
+及超過配額限制的總數量。這些統計數據可用於在線分析或調整方案。
+
+統計數據可以通過讀取方案文件來顯示。讀取該文件將顯示你在每一行中輸入的每個 ``方案`` ,
+統計的五個數字將被加在每一行的末尾。
+
+例子
+~~~~
+
+下面的命令應用了一個方案:”如果一個大小爲[4KiB, 8KiB]的內存區域在[10, 20]的聚合時間
+間隔內顯示出每一個聚合時間間隔[0, 5]的訪問量,請分頁出該區域。對於分頁,每秒最多隻能使
+用10ms,而且每秒分頁不能超過1GiB。在這一限制下,首先分頁出具有較長年齡的內存區域。另外,
+每5秒鐘檢查一次系統的可用內存率,當可用內存率低於50%時開始監測和分頁,但如果可用內存率
+大於60%,或低於30%,則停止監測“::
+
+    # cd <debugfs>/damon
+    # scheme="4096 8192  0 5    10 20    2"  # target access pattern and action
+    # scheme+=" 10 $((1024*1024*1024)) 1000" # quotas
+    # scheme+=" 0 0 100"                     # prioritization weights
+    # scheme+=" 1 5000000 600 500 300"       # watermarks
+    # echo "$scheme" > schemes
+
+
+開關
+----
+
+除非你明確地啓動監測,否則如上所述的文件設置不會產生效果。你可以通過寫入和讀取 ``monitor_on``
+文件來啓動、停止和檢查監測的當前狀態。寫入 ``on`` 該文件可以啓動對有屬性的目標的監測。寫入
+``off`` 該文件則停止這些目標。如果每個目標進程被終止,DAMON也會停止。下面的示例命令開啓、關
+閉和檢查DAMON的狀態::
+
+    # cd <debugfs>/damon
+    # echo on > monitor_on
+    # echo off > monitor_on
+    # cat monitor_on
+    off
+
+請注意,當監測開啓時,你不能寫到上述的debugfs文件。如果你在DAMON運行時寫到這些文件,將會返
+回一個錯誤代碼,如 ``-EBUSY`` 。
+
+
+監測線程PID
+-----------
+
+DAMON通過一個叫做kdamond的內核線程來進行請求監測。你可以通過讀取 ``kdamond_pid`` 文件獲
+得該線程的 ``pid`` 。當監測被 ``關閉`` 時,讀取該文件不會返回任何信息::
+
+    # cd <debugfs>/damon
+    # cat monitor_on
+    off
+    # cat kdamond_pid
+    none
+    # echo on > monitor_on
+    # cat kdamond_pid
+    18594
+
+
+使用多個監測線程
+----------------
+
+每個監測上下文都會創建一個 ``kdamond`` 線程。你可以使用 ``mk_contexts`` 和 ``rm_contexts``
+文件爲多個 ``kdamond`` 需要的用例創建和刪除監測上下文。
+
+將新上下文的名稱寫入 ``mk_contexts`` 文件,在 ``DAMON debugfs`` 目錄上創建一個該名稱的目錄。
+該目錄將有該上下文的 ``DAMON debugfs`` 文件::
+
+    # cd <debugfs>/damon
+    # ls foo
+    # ls: cannot access 'foo': No such file or directory
+    # echo foo > mk_contexts
+    # ls foo
+    # attrs  init_regions  kdamond_pid  schemes  target_ids
+
+如果不再需要上下文,你可以通過把上下文的名字放到 ``rm_contexts`` 文件中來刪除它和相應的目錄::
+
+    # echo foo > rm_contexts
+    # ls foo
+    # ls: cannot access 'foo': No such file or directory
+
+注意, ``mk_contexts`` 、 ``rm_contexts`` 和 ``monitor_on`` 文件只在根目錄下。
+
+
+監測結果的監測點
+================
+
+DAMON通過一個tracepoint ``damon:damon_aggregated`` 提供監測結果.  當監測開啓時,你可
+以記錄追蹤點事件,並使用追蹤點支持工具如perf顯示結果。比如說::
+
+    # echo on > monitor_on
+    # perf record -e damon:damon_aggregated &
+    # sleep 5
+    # kill 9 $(pidof perf)
+    # echo off > monitor_on
+    # perf script
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/index.rst b/Documentation/translations/zh_TW/admin-guide/mm/index.rst
new file mode 100644
index 000000000000..917559614a1f
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/index.rst
@@ -0,0 +1,52 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original:   Documentation/admin-guide/mm/index.rst
+
+:翻譯:
+
+  徐鑫 xu xin <xu.xin16@zte.com.cn>
+
+
+========
+內存管理
+========
+
+Linux內存管理子系統,顧名思義,是負責系統中的內存管理。它包括了虛擬內存與請求
+分頁的實現,內核內部結構和用戶空間程序的內存分配、將文件映射到進程地址空間以
+及許多其他很酷的事情。
+
+Linux內存管理是一個具有許多可配置設置的複雜系統, 且這些設置中的大多數都可以通
+過 ``/proc`` 文件系統獲得,並且可以使用 ``sysctl`` 進行查詢和調整。這些API接
+口被描述在Documentation/admin-guide/sysctl/vm.rst文件和 `man 5 proc`_ 中。
+
+.. _man 5 proc: http://man7.org/linux/man-pages/man5/proc.5.html
+
+Linux內存管理有它自己的術語,如果你還不熟悉它,請考慮閱讀下面參考:
+Documentation/admin-guide/mm/concepts.rst.
+
+在此目錄下,我們詳細描述瞭如何與Linux內存管理中的各種機制交互。
+
+.. toctree::
+   :maxdepth: 1
+
+   damon/index
+   ksm
+
+Todolist:
+* concepts
+* cma_debugfs
+* hugetlbpage
+* idle_page_tracking
+* memory-hotplug
+* nommu-mmap
+* numa_memory_policy
+* numaperf
+* pagemap
+* soft-dirty
+* swap_numa
+* transhuge
+* userfaultfd
+* zswap
+
diff --git a/Documentation/translations/zh_TW/admin-guide/mm/ksm.rst b/Documentation/translations/zh_TW/admin-guide/mm/ksm.rst
new file mode 100644
index 000000000000..3b401c09e7bf
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/mm/ksm.rst
@@ -0,0 +1,201 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/mm/ksm.rst
+
+:翻譯:
+
+  徐鑫 xu xin <xu.xin16@zte.com.cn>
+
+
+============
+內核同頁合併
+============
+
+
+概述
+====
+
+KSM是一種能節省內存的數據去重功能,由CONFIG_KSM=y啓用,並在2.6.32版本時被添
+加到Linux內核。詳見 ``mm/ksm.c`` 的實現,以及http://lwn.net/Articles/306704
+和https://lwn.net/Articles/330589
+
+KSM最初目的是爲了與KVM(即著名的內核共享內存)一起使用而開發的,通過共享虛擬機
+之間的公共數據,將更多虛擬機放入物理內存。但它對於任何會生成多個相同數據實例的
+應用程序都是很有用的。
+
+KSM的守護進程ksmd會定期掃描那些已註冊的用戶內存區域,查找內容相同的頁面,這些
+頁面可以被單個寫保護頁面替換(如果進程以後想要更新其內容,將自動複製)。使用:
+引用:`sysfs intraface  <ksm_sysfs>` 接口來配置KSM守護程序在單個過程中所掃描的頁
+數以及兩個過程之間的間隔時間。
+
+KSM只合並匿名(私有)頁面,從不合並頁緩存(文件)頁面。KSM的合併頁面最初只能被
+鎖定在內核內存中,但現在可以就像其他用戶頁面一樣被換出(但當它們被交換回來時共
+享會被破壞: ksmd必須重新發現它們的身份並再次合併)。
+
+以madvise控制KSM
+================
+
+KSM僅在特定的地址空間區域時運行,即應用程序通過使用如下所示的madvise(2)系統調
+用來請求某塊地址成爲可能的合併候選者的地址空間::
+
+    int madvise(addr, length, MADV_MERGEABLE)
+
+應用程序當然也可以通過調用::
+
+    int madvise(addr, length, MADV_UNMERGEABLE)
+
+來取消該請求,並恢復爲非共享頁面:此時KSM將去除合併在該範圍內的任何合併頁。注意:
+這個去除合併的調用可能突然需要的內存量超過實際可用的內存量-那麼可能會出現EAGAIN
+失敗,但更可能會喚醒OOM killer。
+
+如果KSM未被配置到正在運行的內核中,則madvise MADV_MERGEABLE 和 MADV_UNMERGEABLE
+的調用只會以EINVAL 失敗。如果正在運行的內核是用CONFIG_KSM=y方式構建的,那麼這些
+調用通常會成功:即使KSM守護程序當前沒有運行,MADV_MERGEABLE 仍然會在KSM守護程序
+啓動時註冊範圍,即使該範圍不能包含KSM實際可以合併的任何頁面,即使MADV_UNMERGEABLE
+應用於從未標記爲MADV_MERGEABLE的範圍。
+
+如果一塊內存區域必須被拆分爲至少一個新的MADV_MERGEABLE區域或MADV_UNMERGEABLE區域,
+當該進程將超過 ``vm.max_map_count`` 的設定,則madvise可能返回ENOMEM。(請參閱文檔
+Documentation/admin-guide/sysctl/vm.rst)。
+
+與其他madvise調用一樣,它們在用戶地址空間的映射區域上使用:如果指定的範圍包含未
+映射的間隙(儘管在中間的映射區域工作),它們將報告ENOMEM,如果沒有足夠的內存用於
+內部結構,則可能會因EAGAIN而失敗。
+
+KSM守護進程sysfs接口
+====================
+
+KSM守護進程可以由``/sys/kernel/mm/ksm/`` 中的sysfs文件控制,所有人都可以讀取,但
+只能由root用戶寫入。各接口解釋如下:
+
+
+pages_to_scan
+        ksmd進程進入睡眠前要掃描的頁數。
+        例如, ``echo 100 > /sys/kernel/mm/ksm/pages_to_scan``
+
+        默認值:100(該值被選擇用於演示目的)
+
+sleep_millisecs
+        ksmd在下次掃描前應休眠多少毫秒
+        例如, ``echo 20 > /sys/kernel/mm/ksm/sleep_millisecs``
+
+        默認值:20(該值被選擇用於演示目的)
+
+merge_across_nodes
+        指定是否可以合併來自不同NUMA節點的頁面。當設置爲0時,ksm僅合併在物理上位
+        於同一NUMA節點的內存區域中的頁面。這降低了訪問共享頁面的延遲。在有明顯的
+        NUMA距離上,具有更多節點的系統可能受益於設置該值爲0時的更低延遲。而對於
+        需要對內存使用量最小化的較小系統來說,設置該值爲1(默認設置)則可能會受
+        益於更大共享頁面。在決定使用哪種設置之前,您可能希望比較系統在每種設置下
+        的性能。 ``merge_across_nodes`` 僅當系統中沒有ksm共享頁面時,才能被更改設
+        置:首先將接口`run` 設置爲2從而對頁進行去合併,然後在修改
+        ``merge_across_nodes`` 後再將‘run’又設置爲1,以根據新設置來重新合併。
+
+        默認值:1(如早期的發佈版本一樣合併跨站點)
+
+run
+        * 設置爲0可停止ksmd運行,但保留合併頁面,
+        * 設置爲1可運行ksmd,例如, ``echo 1 > /sys/kernel/mm/ksm/run`` ,
+        * 設置爲2可停止ksmd運行,並且對所有目前已合併的頁進行去合併,但保留可合併
+          區域以供下次運行。
+
+        默認值:0(必須設置爲1才能激活KSM,除非禁用了CONFIG_SYSFS)
+
+use_zero_pages
+        指定是否應當特殊處理空頁(即那些僅含zero的已分配頁)。當該值設置爲1時,
+        空頁與內核零頁合併,而不是像通常情況下那樣空頁自身彼此合併。這可以根據
+        工作負載的不同,在具有着色零頁的架構上可以提高性能。啓用此設置時應小心,
+        因爲它可能會降低某些工作負載的KSM性能,比如,當待合併的候選頁面的校驗和
+        與空頁面的校驗和恰好匹配的時候。此設置可隨時更改,僅對那些更改後再合併
+        的頁面有效。
+
+        默認值:0(如同早期版本的KSM正常表現)
+
+max_page_sharing
+        單個KSM頁面允許的最大共享站點數。這將強制執行重複數據消除限制,以避免涉
+        及遍歷共享KSM頁面的虛擬映射的虛擬內存操作的高延遲。最小值爲2,因爲新創
+        建的KSM頁面將至少有兩個共享者。該值越高,KSM合併內存的速度越快,去重
+        因子也越高,但是對於任何給定的KSM頁面,虛擬映射的最壞情況遍歷的速度也會
+        越慢。減慢了這種遍歷速度就意味着在交換、壓縮、NUMA平衡和頁面遷移期間,
+        某些虛擬內存操作將有更高的延遲,從而降低這些虛擬內存操作調用者的響應能力。
+        其他任務如果不涉及執行虛擬映射遍歷的VM操作,其任務調度延遲不受此參數的影
+        響,因爲這些遍歷本身是調度友好的。
+
+stable_node_chains_prune_millisecs
+        指定KSM檢查特定頁面的元數據的頻率(即那些達到過時信息數據去重限制標準的
+        頁面)單位是毫秒。較小的毫秒值將以更低的延遲來釋放KSM元數據,但它們將使
+        ksmd在掃描期間使用更多CPU。如果還沒有一個KSM頁面達到 ``max_page_sharing``
+        標準,那就沒有什麼用。
+
+KSM與MADV_MERGEABLE的工作有效性體現於 ``/sys/kernel/mm/ksm/`` 路徑下的接口:
+
+pages_shared
+        表示多少共享頁正在被使用
+pages_sharing
+        表示還有多少站點正在共享這些共享頁,即節省了多少
+pages_unshared
+        表示有多少頁是唯一的,但被反覆檢查以進行合併
+pages_volatile
+        表示有多少頁因變化太快而無法放在tree中
+full_scans
+        表示所有可合併區域已掃描多少次
+stable_node_chains
+        達到 ``max_page_sharing`` 限制的KSM頁數
+stable_node_dups
+        重複的KSM頁數
+
+比值 ``pages_sharing/pages_shared`` 的最大值受限制於 ``max_page_sharing``
+的設定。要想增加該比值,則相應地要增加 ``max_page_sharing`` 的值。
+
+監測KSM的收益
+=============
+
+KSM可以通過合併相同的頁面來節省內存,但也會消耗額外的內存,因爲它需要生成一些rmap_items
+來保存每個掃描頁面的簡要rmap信息。其中有些頁面可能會被合併,但有些頁面在被檢查幾次
+後可能無法被合併,這些都是無益的內存消耗。
+
+1) 如何確定KSM在全系統範圍內是節省內存還是消耗內存?這裏有一個簡單的近似計算方法供參考::
+
+       general_profit =~ pages_sharing * sizeof(page) - (all_rmap_items) *
+                         sizeof(rmap_item);
+
+   其中all_rmap_items可以通過對 ``pages_sharing`` 、 ``pages_shared`` 、 ``pages_unshared``
+   和 ``pages_volatile`` 的求和而輕鬆獲得。
+
+2) 單一進程中KSM的收益也可以通過以下近似的計算得到::
+
+       process_profit =~ ksm_merging_pages * sizeof(page) -
+                         ksm_rmap_items * sizeof(rmap_item).
+
+   其中ksm_merging_pages顯示在 ``/proc/<pid>/`` 目錄下,而ksm_rmap_items
+   顯示在 ``/proc/<pid>/ksm_stat`` 。
+
+從應用的角度來看, ``ksm_rmap_items`` 和 ``ksm_merging_pages`` 的高比例意
+味着不好的madvise-applied策略,所以開發者或管理員必須重新考慮如何改變madvis策
+略。舉個例子供參考,一個頁面的大小通常是4K,而rmap_item的大小在32位CPU架構上分
+別是32B,在64位CPU架構上是64B。所以如果 ``ksm_rmap_items/ksm_merging_pages``
+的比例在64位CPU上超過64,或者在32位CPU上超過128,那麼應用程序的madvise策略應
+該被放棄,因爲ksm收益大約爲零或負值。
+
+監控KSM事件
+===========
+
+在/proc/vmstat中有一些計數器,可以用來監控KSM事件。KSM可能有助於節省內存,這是
+一種權衡,因爲它可能會在KSM COW或複製中的交換上遭受延遲。這些事件可以幫助用戶評估
+是否或如何使用KSM。例如,如果cow_ksm增加得太快,用戶可以減少madvise(, , MADV_MERGEABLE)
+的範圍。
+
+cow_ksm
+        在每次KSM頁面觸發寫時拷貝(COW)時都會被遞增,當用戶試圖寫入KSM頁面時,
+        我們必須做一個拷貝。
+
+ksm_swpin_copy
+        在換入時,每次KSM頁被複制時都會被遞增。請注意,KSM頁在換入時可能會被複
+        制,因爲do_swap_page()不能做所有的鎖,而需要重組一個跨anon_vma的KSM頁。
+
+--
+Izik Eidus,
+Hugh Dickins, 2009年11月17日。
+
diff --git a/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst b/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst
index 27638e199f13..fe5a5a07d51a 100644
--- a/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst
+++ b/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst
@@ -1,13 +1,6 @@
 .. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0)
-..
-   If you want to distribute this text under CC-BY-4.0 only, please use 'The
-   Linux kernel developers' for author attribution and link this as source:
-   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/reporting-issues.rst
-..
-   Note: Only the content of this RST file as found in the Linux kernel sources
-   is available under CC-BY-4.0, as versions of this text that were processed
-   (for example by the kernel's build system) might contain content taken from
-   files which use a more restrictive license.
+.. See the bottom of this file for additional redistribution information.
+
 
 .. include:: ../disclaimer-zh_TW.rst
 
@@ -16,7 +9,7 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 
 報告問題
@@ -26,14 +19,16 @@
 簡明指南(亦即 太長不看)
 ==========================
 
-您面臨的是否爲同系列穩定版或長期支持內核的普通內核的回歸?是否仍然受支持?
+您面臨的是否爲同系列穩定版或長期支持內核的普通內核的迴歸?是否仍然受支持?
 請搜索 `LKML內核郵件列表 <https://lore.kernel.org/lkml/>`_ 和
 `Linux穩定版郵件列表 <https://lore.kernel.org/stable/>`_ 存檔中匹配的報告並
 加入討論。如果找不到匹配的報告,請安裝該系列的最新版本。如果它仍然出現問題,
-報告給穩定版郵件列表(stable@vger.kernel.org)。
+請報告給穩定版郵件列表(stable@vger.kernel.org)並抄送回歸郵件列表
+(regressions@lists.linux.dev);理想情況下,還可以抄送維護者和相關子系統的
+郵件列表。
 
 在所有其他情況下,請儘可能猜測是哪個內核部分導致了問題。查看MAINTAINERS文件,
-了解開發人員希望如何得知問題,大多數情況下,報告問題都是通過電子郵件和抄送
+瞭解開發人員希望如何得知問題,大多數情況下,報告問題都是通過電子郵件和抄送
 相關郵件列表進行的。檢查報告目的地的存檔中是否已有匹配的報告;也請搜索
 `LKML <https://lore.kernel.org/lkml/>`_ 和網絡。如果找不到可加入的討論,請
 安裝 `最新的主線內核 <https://kernel.org/>`_ 。如果仍存在問題,請發送報告。
@@ -45,21 +40,22 @@
 
 **通用提醒** :當安裝和測試上述內核時,請確保它是普通的(即:沒有補丁,也沒
 有使用附加模塊)。還要確保它是在一個正常的環境中構建和運行,並且在問題發生
-之前沒有被汙染(tainted)。
+之前沒有被污染(tainted)。
 
-在編寫報告時,要涵蓋與問題相關的所有信息,如使用的內核和發行版。在碰見回歸時,
-嘗試給出引入它的更改的提交ID,二分可以找到它。如果您同時面臨Linux內核的多個
-問題,請分別報告每個問題。
+當你同時面臨Linux內核的多個問題時,請分別報告。在編寫報告時,要涵蓋與問題
+相關的所有信息,如使用的內核和發行版。如果碰見迴歸,請把報告抄送回歸郵件列表
+(regressions@lists.linux.dev)。也請試試用二分法找出源頭;如果成功找到,請
+在報告中寫上它的提交ID並抄送sign-off-by鏈中的所有人。
 
 一旦報告發出,請回答任何出現的問題,並儘可能地提供幫助。這包括通過不時重新
-測試新版本並發送狀態更新來推動進展。
+測試新版本併發送狀態更新來推動進展。
 
 
 如何向內核維護人員報告問題的逐步指南
 =====================================
 
-上面的簡明指南概述了如何向Linux內核開發人員報告問題。對於已經熟悉向自由和開
-源軟體(FLOSS)項目報告問題的人來說,這可能是他們所需要的全部內容。對於其他
+上面的簡明指南概述瞭如何向Linux內核開發人員報告問題。對於已經熟悉向自由和開
+源軟件(FLOSS)項目報告問題的人來說,這可能是他們所需要的全部內容。對於其他
 人,本部分更爲詳細,並一步一步地描述。爲了便於閱讀,它仍然儘量簡潔,並省略
 了許多細節;這些在逐步指南後的參考章節中進行了描述,該章節更詳細地解釋了每
 個步驟。
@@ -68,16 +64,16 @@
 儘早意識到看起來像Linux內核毛病的問題可能實際上是由其他原因引起的。這些步驟
 可以確保你最終不會覺得在這一過程中投入的時間是浪費:
 
- * 您是否面臨硬體或軟體供應商提供的Linux內核的問題?那麼基本上您最好停止閱讀
+ * 您是否面臨硬件或軟件供應商提供的Linux內核的問題?那麼基本上您最好停止閱讀
    本文檔,轉而向您的供應商報告問題,除非您願意自己安裝最新的Linux版本。尋找
    和解決問題往往需要後者。
 
- * 使用您喜愛的網絡搜尋引擎對現有報告進行粗略搜索;此外,請檢查
+ * 使用您喜愛的網絡搜索引擎對現有報告進行粗略搜索;此外,請檢查
    `Linux內核郵件列表(LKML) <https://lore.kernel.org/lkml/>`_ 的存檔。如果
    找到匹配的報告,請加入討論而不是發送新報告。
 
- * 看看你正在處理的問題是否爲回歸問題、安全問題或非常嚴重的問題:這些都是需
-   要在接下來的一些步驟中特別處理的「高優先級問題」。
+ * 看看你正在處理的問題是否爲迴歸問題、安全問題或非常嚴重的問題:這些都是需
+   要在接下來的一些步驟中特別處理的“高優先級問題”。
 
  * 確保不是內核環境導致了您面臨的問題。
 
@@ -86,15 +82,15 @@
  * 確保您的系統不會通過動態構建額外的內核模塊來增強其內核,像DKMS這樣的解決
    方案可能在您不知情的情況下就在本地進行了這樣的工作。
 
- * 當問題發生時,檢查您的內核是否被「汙染」,因爲使內核設置這個標誌的事件可能
+ * 當問題發生時,檢查您的內核是否被“污染”,因爲使內核設置這個標誌的事件可能
    會導致您面臨的問題。
 
  * 粗略地寫下如何重現這個問題。如果您同時處理多個問題,請爲每個問題單獨寫注
    釋,並確保它們在新啓動的系統上獨立出現。這是必要的,因爲每個問題都需要分
    別報告給內核開發人員,除非它們嚴重糾纏在一起。
 
- * 如果您正面臨穩定版或長期支持版本線的回歸(例如從5.10.4更新到5.10.5時出現
-   故障),請查看後文「報告穩定版和長期支持內核線的回歸」小節。
+ * 如果您正面臨穩定版或長期支持版本線的迴歸(例如從5.10.4更新到5.10.5時出現
+   故障),請查看後文“報告穩定版和長期支持內核線的迴歸”小節。
 
  * 定位可能引起問題的驅動程序或內核子系統。找出其開發人員期望的報告的方式和
    位置。注意:大多數情況下不會是 bugzilla.kernel.org,因爲問題通常需要通
@@ -105,61 +101,62 @@
 
 在完成這些準備之後,你將進入主要部分:
 
- * 除非您已經在運行最新的「主線」Linux內核,否則最好在報告流程前安裝它。在某些
-   情況下,使用最新的「穩定版」Linux進行測試和報告也是可以接受的替代方案;在
+ * 除非您已經在運行最新的“主線”Linux內核,否則最好在報告流程前安裝它。在某些
+   情況下,使用最新的“穩定版”Linux進行測試和報告也是可以接受的替代方案;在
    合併窗口期間,這實際上可能是最好的方法,但在開發階段最好還是暫停幾天。無論
-   你選擇什麼版本,最好使用「普通」構建。忽略這些建議會大大增加您的報告被拒絕
+   你選擇什麼版本,最好使用“普通”構建。忽略這些建議會大大增加您的報告被拒絕
    或忽略的風險。
 
- * 確保您剛剛安裝的內核在運行時不會「汙染」自己。
+ * 確保您剛剛安裝的內核在運行時不會“污染”自己。
 
  * 在您剛剛安裝的內核中復現這個問題。如果它沒有出現,請查看下方只發生在
    穩定版和長期支持內核的問題的說明。
 
- * 優化你的筆記:試著找到並寫出最直接的復現問題的方法。確保最終結果包含所有
+ * 優化你的筆記:試着找到並寫出最直接的復現問題的方法。確保最終結果包含所有
    重要的細節,同時讓第一次聽說的人容易閱讀和理解。如果您在此過程中學到了一
    些東西,請考慮再次搜索關於該問題的現有報告。
 
- * 如果失敗涉及「panic」、「Oops」、「warning」或「BUG」,請考慮解碼內核日誌以查找觸
+ * 如果失敗涉及“panic”、“Oops”、“warning”或“BUG”,請考慮解碼內核日誌以查找觸
    發錯誤的代碼行。
 
- * 如果您的問題是回歸問題,請儘可能縮小引入問題時的範圍。
+ * 如果您的問題是迴歸問題,請儘可能縮小引入問題時的範圍。
 
  * 通過詳細描述問題來開始編寫報告。記得包括以下條目:您爲復現而安裝的最新內
    核版本、使用的Linux發行版以及關於如何復現該問題的說明。如果可能,將內核
-   構建配置(.config)和 ``dmesg`` 的輸出放在網上的某個地方,並連結到它。包
+   構建配置(.config)和 ``dmesg`` 的輸出放在網上的某個地方,並鏈接到它。包
    含或上傳所有其他可能相關的信息,如Oops的輸出/截圖或來自 ``lspci`` 的輸出
    。一旦你寫完了這個主要部分,請在上方插入一個正常長度的段落快速概述問題和
    影響。再在此之上添加一個簡單描述問題的句子,以得到人們的閱讀。現在給出一
    個更短的描述性標題或主題。然後就可以像MAINTAINERS文件告訴你的那樣發送或
-   提交報告了,除非你在處理一個「高優先級問題」:它們需要按照下面「高優先級問
-   題的特殊處理」所述特別關照。
+   提交報告了,除非你在處理一個“高優先級問題”:它們需要按照下面“高優先級問
+   題的特殊處理”所述特別關照。
 
  * 等待別人的反應,繼續推進事情,直到你能夠接受這樣或那樣的結果。因此,請公
    開和及時地回應任何詢問。測試提出的修復。積極地測試:至少重新測試每個新主
    線版本的首個候選版本(RC),並報告你的結果。如果出現拖延,就友好地提醒一
-   下。如果你沒有得到任何幫助或者未能滿意,請試著自己幫助自己。
+   下。如果你沒有得到任何幫助或者未能滿意,請試着自己幫助自己。
 
 
-報告穩定版和長期支持內核線的回歸
+報告穩定版和長期支持內核線的迴歸
 ----------------------------------
 
-如果您發現了穩定版或長期支持內核版本線中的回歸問題並按上述流程跳到這裡,那麼
+如果您發現了穩定版或長期支持內核版本線中的迴歸問題並按上述流程跳到這裏,那麼
 請閱讀本小節。即例如您在從5.10.4更新到5.10.5時出現了問題(從5.9.15到5.10.5則
-不是)。開發人員希望儘快修復此類回歸,因此有一個簡化流程來報告它們:
+不是)。開發人員希望儘快修復此類迴歸,因此有一個簡化流程來報告它們:
 
  * 檢查內核開發人員是否仍然維護你關心的Linux內核版本線:去 `kernel.org 的首頁
-   <https://kernel.org/>`_ ,確保此特定版本線的最新版沒有「[EOL]」標記。
+   <https://kernel.org/>`_ ,確保此特定版本線的最新版沒有“[EOL]”標記。
 
  * 檢查 `Linux穩定版郵件列表 <https://lore.kernel.org/stable/>`_ 中的現有報告。
 
- * 從特定的版本線安裝最新版本作爲純淨內核。確保這個內核沒有被汙染,並且仍然
-   存在問題,因爲問題可能已經在那裡被修復了。如果您第一次發現供應商內核的問題,
+ * 從特定的版本線安裝最新版本作爲純淨內核。確保這個內核沒有被污染,並且仍然
+   存在問題,因爲問題可能已經在那裏被修復了。如果您第一次發現供應商內核的問題,
    請檢查已知最新版本的普通構建是否可以正常運行。
 
- * 向Linux穩定版郵件列表發送一個簡短的問題報告(stable@vger.kernel.org)。大致
-   描述問題,並解釋如何復現。講清楚首個出現問題的版本和最後一個工作正常的版本。
-   然後等待進一步的指示。
+ * 向Linux穩定版郵件列表發送一個簡短的問題報告(stable@vger.kernel.org)並抄送
+   Linux迴歸郵件列表(regressions@lists.linux.dev);如果你懷疑是由某子系統
+   引起的,請抄送其維護人員和子系統郵件列表。大致描述問題,並解釋如何復現。
+   講清楚首個出現問題的版本和最後一個工作正常的版本。然後等待進一步的指示。
 
 下面的參考章節部分詳細解釋了這些步驟中的每一步。
 
@@ -167,14 +164,14 @@
 報告只發生在較舊內核版本線的問題
 ----------------------------------
 
-若您嘗試了上述的最新主線內核,但未能在那裡復現問題,那麼本小節適用於您;以下
+若您嘗試了上述的最新主線內核,但未能在那裏復現問題,那麼本小節適用於您;以下
 流程有助於使問題在仍然支持的穩定版或長期支持版本線,或者定期基於最新穩定版或
 長期支持內核的供應商內核中得到修復。如果是這種情況,請執行以下步驟:
 
  * 請做好準備,接下來的幾個步驟可能無法在舊版本中解決問題:修復可能太大或太
-   冒險,無法移植到那裡。
+   冒險,無法移植到那裏。
 
- * 執行前節「報告穩定版和長期支持內核線的回歸」中的前三個步驟。
+ * 執行前節“報告穩定版和長期支持內核線的迴歸”中的前三個步驟。
 
  * 在Linux內核版本控制系統中搜索修復主線問題的更改,因爲它的提交消息可能會
    告訴你修復是否已經計劃好了支持。如果你沒有找到,搜索適當的郵件列表,尋找
@@ -219,14 +216,14 @@
 確保您使用的是上游Linux內核
 ----------------------------
 
-   *您是否面臨硬體或軟體供應商提供的Linux內核的問題?那麼基本上您最好停止閱
+   *您是否面臨硬件或軟件供應商提供的Linux內核的問題?那麼基本上您最好停止閱
    讀本文檔,轉而向您的供應商報告問題,除非您願意自己安裝最新的Linux版本。
    尋找和解決問題往往需要後者。*
 
-與大多數程式設計師一樣,Linux內核開發人員不喜歡花時間處理他們維護的原始碼中根本
-不會發生的問題的報告。這只會浪費每個人的時間,尤其是你的時間。不幸的是,當
+與大多數程序員一樣,Linux內核開發人員不喜歡花時間處理他們維護的源代碼中根本
+不會發生的問題的報告。這隻會浪費每個人的時間,尤其是你的時間。不幸的是,當
 涉及到內核時,這樣的情況很容易發生,並且常常導致雙方氣餒。這是因爲幾乎所有預
-裝在設備(台式機、筆記本電腦、智慧型手機、路由器等)上的Linux內核,以及大多數
+裝在設備(臺式機、筆記本電腦、智能手機、路由器等)上的Linux內核,以及大多數
 由Linux發行商提供的內核,都與由kernel.org發行的官方Linux內核相距甚遠:從Linux
 開發的角度來看,這些供應商提供的內核通常是古老的或者經過了大量修改,通常兩點
 兼具。
@@ -235,19 +232,19 @@
 可能已經由Linux內核開發人員在數月或數年前修復;此外,供應商的修改和增強可能
 會導致您面臨的問題,即使它們看起來很小或者完全不相關。這就是爲什麼您應該向
 供應商報告這些內核的問題。它的開發者應該查看報告,如果它是一個上游問題,直接
-於上游修復或將報告轉發到那裡。在實踐中,這有時行不通。因此,您可能需要考慮
+於上游修復或將報告轉發到那裏。在實踐中,這有時行不通。因此,您可能需要考慮
 通過自己安裝最新的Linux內核內核來繞過供應商。如果如果您選擇此方法,那麼本指
 南後面的步驟將解釋如何在排除了其他可能導致您的問題的原因後執行此操作。
 
-注意前段使用的詞語是「大多數」,因爲有時候開發人員實際上願意處理供應商內核出現
+注意前段使用的詞語是“大多數”,因爲有時候開發人員實際上願意處理供應商內核出現
 的問題報告。他們是否這麼做很大程度上取決於開發人員和相關問題。如果發行版只
 根據最近的Linux版本對內核進行了較小修改,那麼機會就比較大;例如對於Debian
 GNU/Linux Sid或Fedora Rawhide所提供的主線內核。一些開發人員還將接受基於最新
 穩定內核的發行版內核問題報告,只要它改動不大;例如Arch Linux、常規Fedora版本
 和openSUSE Turboweed。但是請記住,您最好使用主線Linux,並避免在此流程中使用
-穩定版內核,如「安裝一個新的內核進行測試」一節中所詳述。
+穩定版內核,如“安裝一個新的內核進行測試”一節中所詳述。
 
-當然,您可以忽略所有這些建議,並向上游Linux開發人員報告舊的或經過大量修改的
+當然,您可以忽略所有這些建議,並向上遊Linux開發人員報告舊的或經過大量修改的
 供應商內核的問題。但是注意,這樣的報告經常被拒絕或忽視,所以自行小心考慮一下。
 不過這還是比根本不報告問題要好:有時候這樣的報告會直接或間接地幫助解決之後的
 問題。
@@ -256,64 +253,61 @@ GNU/Linux Sid或Fedora Rawhide所提供的主線內核。一些開發人員還
 搜索現有報告(第一部分)
 -------------------------
 
-    *使用您喜愛的網絡搜尋引擎對現有報告進行粗略搜索;此外,請檢查Linux內核
+    *使用您喜愛的網絡搜索引擎對現有報告進行粗略搜索;此外,請檢查Linux內核
     郵件列表(LKML)的存檔。如果找到匹配的報告,請加入討論而不是發送新報告。*
 
 報告一個別人已經提出的問題,對每個人來說都是浪費時間,尤其是作爲報告人的你。
 所以徹底檢查是否有人已經報告了這個問題,這對你自己是有利的。在流程中的這一步,
-可以只執行一個粗略的搜索:一旦您知道您的問題需要報告到哪裡,稍後的步驟將告訴
+可以只執行一個粗略的搜索:一旦您知道您的問題需要報告到哪裏,稍後的步驟將告訴
 您如何詳細搜索。儘管如此,不要倉促完成這一步,它可以節省您的時間和減少麻煩。
 
-只需先用你最喜歡的搜尋引擎在網際網路上搜索。然後再搜索Linux內核郵件列表(LKML)
+只需先用你最喜歡的搜索引擎在互聯網上搜索。然後再搜索Linux內核郵件列表(LKML)
 存檔。
 
-如果搜索結果實在太多,可以考慮讓你的搜尋引擎將搜索時間範圍限制在過去的一個
-月或一年。而且無論你在哪裡搜索,一定要用恰當的搜索關鍵詞;也要變化幾次關鍵
-詞。同時,試著從別人的角度看問題:這將幫助你想出其他的關鍵詞。另外,一定不
+如果搜索結果實在太多,可以考慮讓你的搜索引擎將搜索時間範圍限制在過去的一個
+月或一年。而且無論你在哪裏搜索,一定要用恰當的搜索關鍵詞;也要變化幾次關鍵
+詞。同時,試着從別人的角度看問題:這將幫助你想出其他的關鍵詞。另外,一定不
 要同時使用過多的關鍵詞。記住搜索時要同時嘗試包含和不包含內核驅動程序的名稱
-或受影響的硬體組件的名稱等信息。但其確切的品牌名稱(比如說「華碩紅魔 Radeon
-RX 5700 XT Gaming OC」)往往幫助不大,因爲它太具體了。相反,嘗試搜索術語,如
-型號(Radeon 5700 或 Radeon 5000)和核心代號(「Navi」或「Navi10」),以及包含
-和不包含其製造商(「AMD」)。
+或受影響的硬件組件的名稱等信息。但其確切的品牌名稱(比如說“華碩紅魔 Radeon
+RX 5700 XT Gaming OC”)往往幫助不大,因爲它太具體了。相反,嘗試搜索術語,如
+型號(Radeon 5700 或 Radeon 5000)和核心代號(“Navi”或“Navi10”),以及包含
+和不包含其製造商(“AMD”)。
 
 如果你發現了關於你的問題的現有報告,請加入討論,因爲你可能會提供有價值的額
 外信息。這一點很重要,即使是在修復程序已經準備好或處於最後階段,因爲開發人
-員可能會尋找能夠提供額外信息或測試建議修復程序的人。跳到「發布報告後的責任」
-一節,了解有關如何正確參與的細節。
+員可能會尋找能夠提供額外信息或測試建議修復程序的人。跳到“發佈報告後的責任”
+一節,瞭解有關如何正確參與的細節。
 
 注意,搜索 `bugzilla.kernel.org <https://bugzilla.kernel.org/>`_ 網站可能
 也是一個好主意,因爲這可能會提供有價值的見解或找到匹配的報告。如果您發現後者,
-請記住:大多數子系統都希望在不同的位置報告,如下面「你需要將問題報告到何處」
+請記住:大多數子系統都希望在不同的位置報告,如下面“你需要將問題報告到何處”
 一節中所述。因此本應處理這個問題的開發人員甚至可能不知道bugzilla的工單。所以
 請檢查工單中的問題是否已經按照本文檔所述得到報告,如果沒有,請考慮這樣做。
 
 高優先級的問題?
 -----------------
 
-    *看看你正在處理的問題是否是回歸問題、安全問題或非常嚴重的問題:這些都是
-    需要在接下來的一些步驟中特別處理的「高優先級問題」。*
+    *看看你正在處理的問題是否是迴歸問題、安全問題或非常嚴重的問題:這些都是
+    需要在接下來的一些步驟中特別處理的“高優先級問題”。*
 
 Linus Torvalds和主要的Linux內核開發人員希望看到一些問題儘快得到解決,因此在
-報告過程中有一些「高優先級問題」的處理略有不同。有三種情況符合條件:回歸、安全
+報告過程中有一些“高優先級問題”的處理略有不同。有三種情況符合條件:迴歸、安全
 問題和非常嚴重的問題。
 
-如果在舊版本的Linux內核中工作的東西不能在新版本的Linux內核中工作,或者某種
-程度上在新版本的Linux內核中工作得更差,那麼你就需要處理「回歸」。因此,當一個
-在Linux 5.7中表現良好的WiFi驅動程序在5.8中表現不佳或根本不能工作時,這是一
-種回歸。如果應用程式在新的內核中出現不穩定的現象,這也是一種回歸,這可能是
-由於內核和用戶空間之間的接口(如procfs和sysfs)發生不兼容的更改造成的。顯著
-的性能降低或功耗增加也可以稱爲回歸。但是請記住:新內核需要使用與舊內核相似的
-配置來構建(參見下面如何實現這一點)。這是因爲內核開發人員在實現新特性時有
-時無法避免不兼容性;但是爲了避免回歸,這些特性必須在構建配置期間顯式地啓用。
+如果某個應用程序或實際用例在原先的Linux內核上運行良好,但在使用類似配置編譯的
+較新版本上效果更差、或者根本不能用,那麼你就需要處理迴歸問題。
+Documentation/admin-guide/reporting-regressions.rst 對此進行了更詳細的解釋。
+它還提供了很多你可能想知道的關於迴歸的其他信息;例如,它解釋瞭如何將您的問題
+添加到迴歸跟蹤列表中,以確保它不會被忽略。
 
 什麼是安全問題留給您自己判斷。在繼續之前,請考慮閱讀
-「Documentation/translations/zh_TW/admin-guide/security-bugs.rst」,
-因爲它提供了如何最恰當地處理安全問題的額外細節。
+Documentation/translations/zh_CN/admin-guide/security-bugs.rst ,
+因爲它提供瞭如何最恰當地處理安全問題的額外細節。
 
-當發生了完全無法接受的糟糕事情時,此問題就是一個「非常嚴重的問題」。例如,
-Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核突然顯示錯誤消息
-(「kernel panic」)並停止工作,或者根本沒有任何停止信息時,您也在處理一個嚴重
-的問題。注意:不要混淆「panic」(內核停止自身的致命錯誤)和「Oops」(可恢復錯誤),
+當發生了完全無法接受的糟糕事情時,此問題就是一個“非常嚴重的問題”。例如,
+Linux內核破壞了它處理的數據或損壞了它運行的硬件。當內核突然顯示錯誤消息
+(“kernel panic”)並停止工作,或者根本沒有任何停止信息時,您也在處理一個嚴重
+的問題。注意:不要混淆“panic”(內核停止自身的致命錯誤)和“Oops”(可恢復錯誤),
 因爲顯示後者之後內核仍然在運行。
 
 
@@ -325,22 +319,22 @@ Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核
 看起來很像內核問題的問題有時是由構建或運行時環境引起的。很難完全排除這種問
 題,但你應該儘量減少這種問題:
 
- * 構建內核時,請使用經過驗證的工具,因爲編譯器或二進位文件中的錯誤可能會導
+ * 構建內核時,請使用經過驗證的工具,因爲編譯器或二進制文件中的錯誤可能會導
    致內核出現錯誤行爲。
 
  * 確保您的計算機組件在其設計規範內運行;這對處理器、內存和主板尤爲重要。因
    此,當面臨潛在的內核問題時,停止低電壓或超頻。
 
- * 儘量確保不是硬體故障導致了你的問題。例如,內存損壞會導致大量的問題,這些
+ * 儘量確保不是硬件故障導致了你的問題。例如,內存損壞會導致大量的問題,這些
    問題會表現爲看起來像內核問題。
 
  * 如果你正在處理一個文件系統問題,你可能需要用 ``fsck`` 檢查一下文件系統,
    因爲它可能會以某種方式被損壞,從而導致無法預期的內核行爲。
 
- * 在處理回歸問題時,要確保沒有在更新內核的同時發生了其他變化。例如,這個問
-   題可能是由同時更新的其他軟體引起的。也有可能是在你第一次重啓進入新內核時,
-   某個硬體巧合地壞了。更新系統 BIOS 或改變 BIOS 設置中的某些內容也會導致
-   一些看起來很像內核回歸的問題。
+ * 在處理迴歸問題時,要確保沒有在更新內核的同時發生了其他變化。例如,這個問
+   題可能是由同時更新的其他軟件引起的。也有可能是在你第一次重啓進入新內核時,
+   某個硬件巧合地壞了。更新系統 BIOS 或改變 BIOS 設置中的某些內容也會導致
+   一些看起來很像內核迴歸的問題。
 
 
 爲緊急情況做好準備
@@ -349,8 +343,8 @@ Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核
     *創建一個全新的備份,並將系統修復和還原工具放在手邊*
 
 我得提醒您,您正在和計算機打交道,計算機有時會出現意想不到的事情,尤其是當
-您折騰其作業系統的內核等關鍵部件時。而這就是你在這個過程中要做的事情。因此,
-一定要創建一個全新的備份;還要確保你手頭有修復或重裝作業系統的所有工具,
+您折騰其操作系統的內核等關鍵部件時。而這就是你在這個過程中要做的事情。因此,
+一定要創建一個全新的備份;還要確保你手頭有修復或重裝操作系統的所有工具,
 以及恢復備份所需的一切。
 
 
@@ -366,67 +360,67 @@ Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核
 的任何模塊。然後重新啓動再繼續。
 
 注意,你可能不知道你的系統正在使用這些解決方案之一:當你安裝 Nvidia 專有圖
-形驅動程序、VirtualBox 或其他需要 Linux 內核以外的模塊支持的軟體時,它們通
-常會靜默設置。這就是爲什麼你可能需要卸載這些軟體的軟體包,以擺脫任何第三方
+形驅動程序、VirtualBox 或其他需要 Linux 內核以外的模塊支持的軟件時,它們通
+常會靜默設置。這就是爲什麼你可能需要卸載這些軟件的軟件包,以擺脫任何第三方
 內核模塊。
 
 
-檢測「汙染」標誌
+檢查“污染”標誌
 ----------------
 
-    *當問題發生時,檢查您的內核是否被「汙染」,因爲使內核設置這個標誌的事件可
+    *當問題發生時,檢查您的內核是否被“污染”,因爲使內核設置這個標誌的事件可
     能會導致您面臨的問題。*
 
-當某些可能會導致看起來完全不相關的後續錯誤的事情發生時,內核會用「汙染
-(taint)」標誌標記自己。如果您的內核受到汙染,那麼您面臨的可能是這樣的錯誤。
+當某些可能會導致看起來完全不相關的後續錯誤的事情發生時,內核會用“污染
+(taint)”標誌標記自己。如果您的內核受到污染,那麼您面臨的可能是這樣的錯誤。
 因此在投入更多時間到這個過程中之前,儘早排除此情況可能對你有好處。這是這個
-步驟出現在這裡的唯一原因,因爲這個過程稍後會告訴您安裝最新的主線內核;然後
-您將需要再次檢查汙染標誌,因爲當它出問題的時候內核報告會關注它。
+步驟出現在這裏的唯一原因,因爲這個過程稍後會告訴您安裝最新的主線內核;然後
+您將需要再次檢查污染標誌,因爲當它出問題的時候內核報告會關注它。
 
-在正在運行的系統上檢查內核是否汙染非常容易:如果 ``cat /proc/sys/kernel/tainted``
-返回「0」,那麼內核沒有被汙染,一切正常。在某些情況下無法檢查該文件;這就是
-爲什麼當內核報告內部問題(「kernel bug」)、可恢復錯誤(「kernel Oops」)或停止
-操作前不可恢復的錯誤(「kernel panic」)時,它也會提到汙染狀態。當其中一個錯
-誤發生時,查看列印的錯誤消息的頂部,搜索以「CPU:」開頭的行。如果發現問題時內
-核未被汙染,那麼它應該以「Not infected」結束;如果你看到「Tainted:」且後跟一些
-空格和字母,那就被汙染了。
+在正在運行的系統上檢查內核是否污染非常容易:如果 ``cat /proc/sys/kernel/tainted``
+返回“0”,那麼內核沒有被污染,一切正常。在某些情況下無法檢查該文件;這就是
+爲什麼當內核報告內部問題(“kernel bug”)、可恢復錯誤(“kernel Oops”)或停止
+操作前不可恢復的錯誤(“kernel panic”)時,它也會提到污染狀態。當其中一個錯
+誤發生時,查看打印的錯誤消息的頂部,搜索以“CPU:”開頭的行。如果發現問題時內
+核未被污染,那麼它應該以“Not infected”結束;如果你看到“Tainted:”且後跟一些
+空格和字母,那就被污染了。
 
-如果你的內核被汙染了,請閱讀「Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst」
-以找出原因。設法消除汙染因素。通常是由以下三種因素之一引起的:
+如果你的內核被污染了,請閱讀 Documentation/translations/zh_CN/admin-guide/tainted-kernels.rst
+以找出原因。設法消除污染因素。通常是由以下三種因素之一引起的:
 
- 1. 發生了一個可恢復的錯誤(「kernel Oops」),內核汙染了自己,因爲內核知道在
+ 1. 發生了一個可恢復的錯誤(“kernel Oops”),內核污染了自己,因爲內核知道在
     此之後它可能會出現奇怪的行爲錯亂。在這種情況下,檢查您的內核或系統日誌,
     並尋找以下列文字開頭的部分::
 
        Oops: 0000 [#1] SMP
 
-    如方括號中的「#1」所示,這是自啓動以來的第一次Oops。每個Oops和此後發生的
+    如方括號中的“#1”所示,這是自啓動以來的第一次Oops。每個Oops和此後發生的
     任何其他問題都可能是首個Oops的後續問題,即使這兩個問題看起來完全不相關。
     通過消除首個Oops的原因並在之後復現該問題,可以排除這種情況。有時僅僅
     重新啓動就足夠了,有時更改配置後重新啓動可以消除Oops。但是在這個流程中
     不要花費太多時間在這一點上,因爲引起Oops的原因可能已經在您稍後將按流程
     安裝的新Linux內核版本中修復了。
 
- 2. 您的系統使用的軟體安裝了自己的內核模塊,例如Nvidia的專有圖形驅動程序或
-    VirtualBox。當內核從外部源(即使它們是開源的)加載此類模塊時,它會汙染
+ 2. 您的系統使用的軟件安裝了自己的內核模塊,例如Nvidia的專有圖形驅動程序或
+    VirtualBox。當內核從外部源(即使它們是開源的)加載此類模塊時,它會污染
     自己:它們有時會在不相關的內核區域導致錯誤,從而可能導致您面臨的問題。
     因此,當您想要向Linux內核開發人員報告問題時,您必須阻止這些模塊加載。
-    大多數情況下最簡單的方法是:臨時卸載這些軟體,包括它們可能已經安裝的任
+    大多數情況下最簡單的方法是:臨時卸載這些軟件,包括它們可能已經安裝的任
     何模塊。之後重新啓動。
 
- 3. 當內核加載駐留在Linux內核原始碼staging樹中的模塊時,它也會汙染自身。這
+ 3. 當內核加載駐留在Linux內核源代碼staging樹中的模塊時,它也會污染自身。這
     是一個特殊的區域,代碼(主要是驅動程序)還沒有達到正常Linux內核的質量
-    標準。當您報告此種模塊的問題時,內核受到汙染顯然是沒有問題的;只需確保
-    問題模塊是造成汙染的唯一原因。如果問題發生在一個不相關的區域,重新啓動
+    標準。當您報告此種模塊的問題時,內核受到污染顯然是沒有問題的;只需確保
+    問題模塊是造成污染的唯一原因。如果問題發生在一個不相關的區域,重新啓動
     並通過指定 ``foo.blacklist=1`` 作爲內核參數臨時阻止該模塊被加載(用有
-    問題的模塊名替換「foo」)。
+    問題的模塊名替換“foo”)。
 
 
 記錄如何重現問題
 ------------------
 
     *粗略地寫下如何重現這個問題。如果您同時處理多個問題,請爲每個問題單獨寫
-    注釋,並確保它們在新啓動的系統上獨立出現。這是必要的,因爲每個問題都需
+    註釋,並確保它們在新啓動的系統上獨立出現。這是必要的,因爲每個問題都需
     要分別報告給內核開發人員,除非它們嚴重糾纏在一起。*
 
 如果你同時處理多個問題,必須分別報告每個問題,因爲它們可能由不同的開發人員
@@ -438,20 +432,20 @@ Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核
 
 注意:報告只發生過一次的問題往往是沒有結果的,因爲它們可能是由於宇宙輻射導
 致的位翻轉。所以你應該嘗試通過重現問題來排除這種情況,然後再繼續。如果你有
-足夠的經驗來區分由於硬體故障引起的一次性錯誤和難以重現的罕見內核問題,可以
+足夠的經驗來區分由於硬件故障引起的一次性錯誤和難以重現的罕見內核問題,可以
 忽略這個建議。
 
 
-穩定版或長期支持內核的回歸?
+穩定版或長期支持內核的迴歸?
 -----------------------------
 
-    *如果您正面臨穩定版或長期支持版本線的回歸(例如從5.10.4更新到5.10.5時出現
-    故障),請查看後文「報告穩定版和長期支持內核線的回歸」小節。*
+    *如果您正面臨穩定版或長期支持版本線的迴歸(例如從5.10.4更新到5.10.5時出現
+    故障),請查看後文“報告穩定版和長期支持內核線的迴歸”小節。*
 
-穩定版和長期支持內核版本線中的回歸是Linux開發人員非常希望解決的問題,這樣的
-問題甚至比主線開發分支中的回歸更不應出現,因爲它們會很快影響到很多人。開發人員
-希望儘快了解此類問題,因此有一個簡化流程來報告這些問題。注意,使用更新內核版
-本線的回歸(比如從5.9.15切換到5.10.5時出現故障)不符合條件。
+穩定版和長期支持內核版本線中的迴歸是Linux開發人員非常希望解決的問題,這樣的
+問題甚至比主線開發分支中的迴歸更不應出現,因爲它們會很快影響到很多人。開發人員
+希望儘快瞭解此類問題,因此有一個簡化流程來報告這些問題。注意,使用更新內核版
+本線的迴歸(比如從5.9.15切換到5.10.5時出現故障)不符合條件。
 
 
 你需要將問題報告到何處
@@ -462,9 +456,9 @@ Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核
     過郵件發送給維護人員和公共郵件列表。*
 
 將報告發送給合適的人是至關重要的,因爲Linux內核是一個大項目,大多數開發人員
-只熟悉其中的一小部分。例如,相當多的程式設計師只關心一個驅動程序,比如一個WiFi
-晶片驅動程序;它的開發人員可能對疏遠的或不相關的「子系統」(如TCP堆棧、
-PCIe/PCI子系統、內存管理或文件系統)的內部知識了解很少或完全不了解。
+只熟悉其中的一小部分。例如,相當多的程序員只關心一個驅動程序,比如一個WiFi
+芯片驅動程序;它的開發人員可能對疏遠的或不相關的“子系統”(如TCP堆棧、
+PCIe/PCI子系統、內存管理或文件系統)的內部知識瞭解很少或完全不瞭解。
 
 問題在於:Linux內核缺少一個,可以簡單地將問題歸檔並讓需要了解它的開發人員了
 解它的,中心化缺陷跟蹤器。這就是爲什麼你必須找到正確的途徑來自己報告問題。
@@ -476,10 +470,10 @@ PCIe/PCI子系統、內存管理或文件系統)的內部知識了解很少或
 
 爲了說明如何使用 :ref:`MAINTAINERS <maintainers>` 文件,讓我們假設您的筆記
 本電腦中的WiFi在更新內核後突然出現了錯誤行爲。這種情況下可能是WiFi驅動的問
-題。顯然,它也可能由於驅動基於的某些代碼,但除非你懷疑有這樣的東西會附著在
-驅動程序上。如果真的是其他的問題,驅動程序的開發人員會讓合適的人參與進來。
+題。顯然,它也可能由於驅動基於的某些代碼,但除非你懷疑有這樣的東西會附着在
+驅動程序上。如果真的是其他的問題,驅動程序的開發人員會讓合適的人蔘與進來。
 
-遺憾的是,沒有通用且簡單的辦法來檢查哪個代碼驅動了特定硬體組件。
+遺憾的是,沒有通用且簡單的辦法來檢查哪個代碼驅動了特定硬件組件。
 
 在WiFi驅動出現問題的情況下,你可能想查看 ``lspci -k`` 的輸出,因爲它列出了
 PCI/PCIe總線上的設備和驅動它的內核模塊::
@@ -492,19 +486,19 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
          Kernel modules: ath10k_pci
        [...]
 
-但如果你的WiFi晶片通過USB或其他內部總線連接,這種方法就行不通了。在這種情況
+但如果你的WiFi芯片通過USB或其他內部總線連接,這種方法就行不通了。在這種情況
 下,您可能需要檢查您的WiFi管理器或 ``ip link`` 的輸出。尋找有問題的網絡接口
-的名稱,它可能類似於「wlp58s0」。此名稱可以用來找到驅動它的模塊::
+的名稱,它可能類似於“wlp58s0”。此名稱可以用來找到驅動它的模塊::
 
        [user@something ~]$ realpath --relative-to=/sys/module//sys/class/net/wlp58s0/device/driver/module
        ath10k_pci
 
 如果這些技巧不能進一步幫助您,請嘗試在網上搜索如何縮小相關驅動程序或子系統
-的範圍。如果你不確定是哪一個:試著猜一下,即使你猜得不好,也會有人會幫助你
+的範圍。如果你不確定是哪一個:試着猜一下,即使你猜得不好,也會有人會幫助你
 的。
 
 一旦您知道了相應的驅動程序或子系統,您就希望在MAINTAINERS文件中搜索它。如果
-是「ath10k_pci」,您不會找到任何東西,因爲名稱太具體了。有時你需要在網上尋找
+是“ath10k_pci”,您不會找到任何東西,因爲名稱太具體了。有時你需要在網上尋找
 幫助;但在此之前,請嘗試使用一個稍短或修改過的名稱來搜索MAINTAINERS文件,因
 爲這樣你可能會發現類似這樣的東西::
 
@@ -516,23 +510,23 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
        SCM:           git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
        Files:         drivers/net/wireless/ath/ath10k/
 
-注意:如果您閱讀在Linux原始碼樹的根目錄中找到的原始維護者文件,則行描述將是
-縮寫。例如,「Mail:(郵件)」將是「M:」,「Mailing list:(郵件列表)」將是「L」,
-「Status:(狀態)」將是「S:」。此文件頂部有一段解釋了這些和其他縮寫。
+注意:如果您閱讀在Linux源代碼樹的根目錄中找到的原始維護者文件,則行描述將是
+縮寫。例如,“Mail:(郵件)”將是“M:”,“Mailing list:(郵件列表)”將是“L”,
+“Status:(狀態)”將是“S:”。此文件頂部有一段解釋了這些和其他縮寫。
 
-首先查看「Status」狀態行。理想情況下,它應該得到「Supported(支持)」或
-「Maintained(維護)」。如果狀態爲「Obsolete(過時的)」,那麼你在使用一些過時的
-方法,需要轉換到新的解決方案上。有時候,只有在感到有動力時,才會有人爲代碼
-提供「Odd Fixes」。如果碰見「Orphan」,你就完全不走運了,因爲再也沒有人關心代碼
-了,只剩下這些選項:準備好與問題共存,自己修復它,或者找一個願意修復它的程式設計師。
+首先查看“Status”狀態行。理想情況下,它應該得到“Supported(支持)”或
+“Maintained(維護)”。如果狀態爲“Obsolete(過時的)”,那麼你在使用一些過時的
+方法,需要轉換到新的解決方案上。有時候,只有在感到有動力時,纔會有人爲代碼
+提供“Odd Fixes”。如果碰見“Orphan”,你就完全不走運了,因爲再也沒有人關心代碼
+了,只剩下這些選項:準備好與問題共存,自己修復它,或者找一個願意修復它的程序員。
 
-檢查狀態後,尋找以「bug:」開頭的一行:它將告訴你在哪裡可以找到子系統特定的缺
+檢查狀態後,尋找以“bug:”開頭的一行:它將告訴你在哪裏可以找到子系統特定的缺
 陷跟蹤器來提交你的問題。上面的例子沒有此行。大多數部分都是這樣,因爲 Linux
 內核的開發完全是由郵件驅動的。很少有子系統使用缺陷跟蹤器,且其中只有一部分
 依賴於 bugzilla.kernel.org。
 
-在這種以及其他很多情況下,你必須尋找以「Mail:」開頭的行。這些行提到了特定代碼
-的維護者的名字和電子郵件地址。也可以查找以「Mailing list:」開頭的行,它告訴你
+在這種以及其他很多情況下,你必須尋找以“Mail:”開頭的行。這些行提到了特定代碼
+的維護者的名字和電子郵件地址。也可以查找以“Mailing list:”開頭的行,它告訴你
 開發代碼的公共郵件列表。你的報告之後需要通過郵件發到這些地址。另外,對於所有
 通過電子郵件發送的問題報告,一定要抄送 Linux Kernel Mailing List(LKML)
 <linux-kernel@vger.kernel.org>。在以後通過郵件發送問題報告時,不要遺漏任何
@@ -544,8 +538,8 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
 ~~~~~~~~~~~~~~~~~~~~
 
 對於手頭有Linux源碼的人來說,有第二個可以找到合適的報告地點的選擇:腳本
-「scripts/get_maintainer.pl」,它嘗試找到所有要聯繫的人。它會查詢MAINTAINERS
-文件,並需要用相關原始碼的路徑來調用。對於編譯成模塊的驅動程序,經常可以用
+“scripts/get_maintainer.pl”,它嘗試找到所有要聯繫的人。它會查詢MAINTAINERS
+文件,並需要用相關源代碼的路徑來調用。對於編譯成模塊的驅動程序,經常可以用
 這樣的命令找到::
 
        $ modinfo ath10k_pci | grep filename | sed 's!/lib/modules/.*/kernel/!!; s!filename:!!; s!\.ko\(\|\.xz\)!!'
@@ -561,13 +555,13 @@ PCI/PCIe總線上的設備和驅動它的內核模塊::
        netdev@vger.kernel.org (open list:NETWORKING DRIVERS)
        linux-kernel@vger.kernel.org (open list)
 
-不要把你的報告發給所有的人。發送給維護者,腳本稱之爲「supporter:」;另外抄送
+不要把你的報告發給所有的人。發送給維護者,腳本稱之爲“supporter:”;另外抄送
 代碼最相關的郵件列表,以及 Linux 內核郵件列表(LKML)。在此例中,你需要將報
-告發送給 「Some Human <shuman@example.com>」 ,並抄送
-「ath10k@lists.infradead.org」和「linux-kernel@vger.kernel.org」。
+告發送給 “Some Human <shuman@example.com>” ,並抄送
+“ath10k@lists.infradead.org”和“linux-kernel@vger.kernel.org”。
 
-注意:如果你用 git 克隆了 Linux 原始碼,你可能需要用--git 再次調用
-get_maintainer.pl。腳本會查看提交歷史,以找到最近哪些人參與了相關代碼的編寫,
+注意:如果你用 git 克隆了 Linux 源代碼,你可能需要用--git 再次調用
+get_maintainer.pl。腳本會查看提交歷史,以找到最近哪些人蔘與了相關代碼的編寫,
 因爲他們可能會提供幫助。但要小心使用這些結果,因爲它很容易讓你誤入歧途。
 例如,這種情況常常會發生在很少被修改的地方(比如老舊的或未維護的驅動程序):
 有時這樣的代碼會在樹級清理期間被根本不關心此驅動程序的開發者修改。
@@ -580,73 +574,74 @@ get_maintainer.pl。腳本會查看提交歷史,以找到最近哪些人參與
     如果找到匹配的報告,請加入討論而不是發送新報告。*
 
 如前所述:報告一個別人已經提出的問題,對每個人來說都是浪費時間,尤其是作爲報告
-人的你。這就是爲什麼你應該再次搜索現有的報告。現在你已經知道問題需要報告到哪裡。
+人的你。這就是爲什麼你應該再次搜索現有的報告。現在你已經知道問題需要報告到哪裏。
 如果是郵件列表,那麼一般在 `lore.kernel.org <https://lore.kernel.org/>`_ 可以
 找到相應存檔。
 
 但有些列表運行在其他地方。例如前面步驟中當例子的ath10k WiFi驅動程序就是這種
-情況。但是你通常可以在網上很容易地找到這些列表的檔案。例如搜索「archive
-ath10k@lists.infradead.org」,將引導您到ath10k郵件列表的信息頁,該頁面頂部連結
+情況。但是你通常可以在網上很容易地找到這些列表的檔案。例如搜索“archive
+ath10k@lists.infradead.org”,將引導您到ath10k郵件列表的信息頁,該頁面頂部鏈接
 到其 `列表存檔 <https://lists.infradead.org/pipermail/ath10k/>`_ 。遺憾的是,
-這個列表和其他一些列表缺乏搜索其存檔的功能。在這種情況下可以使用常規的網際網路
-搜尋引擎,並添加類似「site:lists.infadead.org/pipermail/ath10k/」這
-樣的搜索條件,這會把結果限制在該連結中的檔案。
+這個列表和其他一些列表缺乏搜索其存檔的功能。在這種情況下可以使用常規的互聯網
+搜索引擎,並添加類似“site:lists.infadead.org/pipermail/ath10k/”這
+樣的搜索條件,這會把結果限制在該鏈接中的檔案。
 
-也請進一步搜索網絡、LKML和bugzilla.kernel.org網站。
+也請進一步搜索網絡、LKML和bugzilla.kernel.org網站。如果你的報告需要發送到缺陷
+跟蹤器中,那麼您可能還需要檢查子系統的郵件列表存檔,因爲可能有人只在那裏報告了它。
 
-有關如何搜索以及在找到匹配報告時如何操作的詳細信息,請參閱上面的「搜索現有報告
-(第一部分)」。
+有關如何搜索以及在找到匹配報告時如何操作的詳細信息,請參閱上面的“搜索現有報告
+(第一部分)”。
 
-不要急著完成報告過程的這一步:花30到60分鐘甚至更多的時間可以爲你和其他人節省 /
+不要急着完成報告過程的這一步:花30到60分鐘甚至更多的時間可以爲你和其他人節省 /
 減少相當多的時間和麻煩。
 
 
 安裝一個新的內核進行測試
 --------------------------
 
-    *除非您已經在運行最新的「主線」Linux內核,否則最好在報告流程前安裝它。在
-    某些情況下,使用最新的「穩定版」Linux進行測試和報告也是可以接受的替代方案;
+    *除非您已經在運行最新的“主線”Linux內核,否則最好在報告流程前安裝它。在
+    某些情況下,使用最新的“穩定版”Linux進行測試和報告也是可以接受的替代方案;
     在合併窗口期間,這實際上可能是最好的方法,但在開發階段最好還是暫停幾天。
-    無論你選擇什麼版本,最好使用「普通」構建。忽略這些建議會大大增加您的報告
+    無論你選擇什麼版本,最好使用“普通”構建。忽略這些建議會大大增加您的報告
     被拒絕或忽略的風險。*
 
-正如第一步的詳細解釋中所提到的:與大多數程式設計師一樣,與大多數程式設計師一樣,Linux
-內核開發人員不喜歡花時間處理他們維護的原始碼中根本不會發生的問題的報告。這隻
+正如第一步的詳細解釋中所提到的:與大多數程序員一樣,與大多數程序員一樣,Linux
+內核開發人員不喜歡花時間處理他們維護的源代碼中根本不會發生的問題的報告。這隻
 會浪費每個人的時間,尤其是你的時間。這就是爲什麼在報告問題之前,您必須先確認
 問題仍然存在於最新的上游代碼中,這符合每個人的利益。您可以忽略此建議,但如前
 所述:這樣做會極大地增加問題報告被拒絕或被忽略的風險。
 
-內核「最新上游」的範圍通常指:
+內核“最新上游”的範圍通常指:
 
  * 安裝一個主線內核;最新的穩定版內核也可以是一個選擇,但大多數時候都最好避免。
-   長期支持內核(有時稱爲「LTS內核」)不適合此流程。下一小節將更詳細地解釋所有
+   長期支持內核(有時稱爲“LTS內核”)不適合此流程。下一小節將更詳細地解釋所有
    這些。
 
  * 下一小節描述獲取和安裝這樣一個內核的方法。它還指出了使用預編譯內核是可以的,
-   但普通的內核更好,這意味著:它是直接使用從 `kernel.org <https://kernel.org/>`_
-   獲得的Linux原始碼構建並且沒有任何方式修改或增強。
+   但普通的內核更好,這意味着:它是直接使用從 `kernel.org <https://kernel.org/>`_
+   獲得的Linux源代碼構建並且沒有任何方式修改或增強。
 
 
 選擇適合測試的版本
 ~~~~~~~~~~~~~~~~~~~~
 
-前往 `kernel.org <https://kernel.org/>`_ 來決定使用哪個版本。忽略那個寫著
-「Latest release最新版本」的巨大黃色按鈕,往下看有一個表格。在表格的頂部,你會
-看到一行以「mainline」開頭的字樣,大多數情況下它會指向一個版本號類似「5.8-rc2」
-的預發布版本。如果是這樣的話,你將需要使用這個主線內核進行測試。不要讓「rc」
-嚇到你,這些「開發版內核」實際上非常可靠——而且你已經按照上面的指示做了備份,
+前往 `kernel.org <https://kernel.org/>`_ 來決定使用哪個版本。忽略那個寫着
+“Latest release最新版本”的巨大黃色按鈕,往下看有一個表格。在表格的頂部,你會
+看到一行以“mainline”開頭的字樣,大多數情況下它會指向一個版本號類似“5.8-rc2”
+的預發佈版本。如果是這樣的話,你將需要使用這個主線內核進行測試。不要讓“rc”
+嚇到你,這些“開發版內核”實際上非常可靠——而且你已經按照上面的指示做了備份,
 不是嗎?
 
-大概每九到十周,「mainline」可能會給你指出一個版本號類似「5.7」的正式版本。如果
-碰見這種情況,請考慮暫停報告過程,直到下一個版本的第一個預發布(5.8-rc1)出
-現在 `kernel.org <https://kernel.org/>`_ 上。這是因爲 Linux 的開發周期正在
-兩周的「合併窗口」內。大部分的改動和所有干擾性的改動都會在這段時間內被合併到
+大概每九到十週,“mainline”可能會給你指出一個版本號類似“5.7”的正式版本。如果
+碰見這種情況,請考慮暫停報告過程,直到下一個版本的第一個預發佈(5.8-rc1)出
+現在 `kernel.org <https://kernel.org/>`_ 上。這是因爲 Linux 的開發週期正在
+兩週的“合併窗口”內。大部分的改動和所有干擾性的改動都會在這段時間內被合併到
 下一個版本中。在此期間使用主線是比較危險的。內核開發者通常也很忙,可能沒有
 多餘的時間來處理問題報告。這也是很有可能在合併窗口中應用了許多修改來修復你
-所面臨的問題;這就是爲什麼你很快就得用一個新的內核版本重新測試,就像下面「發
-布報告後的責任」一節中所述的那樣。
+所面臨的問題;這就是爲什麼你很快就得用一個新的內核版本重新測試,就像下面“發
+布報告後的責任”一節中所述的那樣。
 
-這就是爲什麼要等到合併窗口結束後才去做。但是如果你處理的是一些不應該等待的
+這就是爲什麼要等到合併窗口結束後纔去做。但是如果你處理的是一些不應該等待的
 東西,則無需這樣做。在這種情況下,可以考慮通過 git 獲取最新的主線內核(見下
 文),或者使用 kernel.org 上提供的最新穩定版本。如果 mainline 因爲某些原因
 不無法正常工作,那麼使用它也是可以接受的。總的來說:用它來重現問題也比完全
@@ -657,7 +652,7 @@ ath10k@lists.infradead.org」,將引導您到ath10k郵件列表的信息頁,
 需要先在主線修復,然後才能得到回傳,這可能需要幾天或幾周。另一個原因是:您
 希望的修復對於回傳來說可能太難或太冒險;因此再次報告問題不太可能改變任何事情。
 
-這些方面也部分表明了爲什麼長期支持內核(有時稱爲「LTS內核」)不適合報告流程:
+這些方面也部分表明了爲什麼長期支持內核(有時稱爲“LTS內核”)不適合報告流程:
 它們與當前代碼的距離太遠。因此,先去測試主線,然後再按流程走:如果主線沒有
 出現問題,流程將指導您如何在舊版本線中修復它。
 
@@ -669,31 +664,31 @@ ath10k@lists.infradead.org」,將引導您到ath10k郵件列表的信息頁,
 
 **使用預編譯的內核** :這往往是最快速、最簡單、最安全的方法——尤其是在你不熟
 悉 Linux 內核的情況下。問題是:發行商或附加存儲庫提供的大多數版本都是從修改
-過的Linux原始碼構建的。因此它們不是普通的,通常不適合於測試和問題報告:這些
+過的Linux源代碼構建的。因此它們不是普通的,通常不適合於測試和問題報告:這些
 更改可能會導致您面臨的問題或以某種方式影響問題。
 
 但是如果您使用的是流行的Linux發行版,那麼您就很幸運了:對於大部分的發行版,
 您可以在網上找到包含最新主線或穩定版本Linux內核包的存儲庫。使用這些是完全可
-以的,只要從存儲庫的描述中確認它們是普通的或者至少接近普通。此外,請確保軟體
-包包含kernel.org上提供的最新版本內核。如果這些軟體包的時間超過一周,那麼它們
-可能就不合適了,因爲新的主線和穩定版內核通常至少每周發布一次。
+以的,只要從存儲庫的描述中確認它們是普通的或者至少接近普通。此外,請確保軟件
+包包含kernel.org上提供的最新版本內核。如果這些軟件包的時間超過一週,那麼它們
+可能就不合適了,因爲新的主線和穩定版內核通常至少每週發佈一次。
 
 請注意,您以後可能需要手動構建自己的內核:有時這是調試或測試修復程序所必需的,
 如後文所述。還要注意,預編譯的內核可能缺少在出現panic、Oops、warning或BUG時
-解碼內核列印的消息所需的調試符號;如果您計劃解碼這些消息,最好自己編譯內核
-(有關詳細信息,請參閱本小節結尾和「解碼失敗信息」小節)。
+解碼內核打印的消息所需的調試符號;如果您計劃解碼這些消息,最好自己編譯內核
+(有關詳細信息,請參閱本小節結尾和“解碼失敗信息”小節)。
 
 **使用git** :熟悉 git 的開發者和有經驗的 Linux 用戶通常最好直接從
 `kernel.org 上的官方開發倉庫
 <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/>`_
-中獲取最新的 Linux 內核原始碼。這些很可能比最新的主線預發布版本更新一些。不
-用擔心:它們和正式的預發布版本一樣可靠,除非內核的開發周期目前正處於合併窗
+中獲取最新的 Linux 內核源代碼。這些很可能比最新的主線預發佈版本更新一些。不
+用擔心:它們和正式的預發佈版本一樣可靠,除非內核的開發週期目前正處於合併窗
 口中。不過即便如此,它們也是相當可靠的。
 
 **常規方法** :不熟悉 git 的人通常最好從 `kernel.org <https://kernel.org/>`_
 下載源碼的tar 存檔包。
 
-如何實際構建一個內核並不在這裡描述,因爲許多網站已經解釋了必要的步驟。如果
+如何實際構建一個內核並不在這裏描述,因爲許多網站已經解釋了必要的步驟。如果
 你是新手,可以考慮按照那些建議使用 ``make localmodconfig`` 來做,它將嘗試獲
 取你當前內核的配置,然後根據你的系統進行一些調整。這樣做並不能使編譯出來的
 內核更好,但可以更快地編譯。
@@ -702,19 +697,19 @@ ath10k@lists.infradead.org」,將引導您到ath10k郵件列表的信息頁,
 啓用 CONFIG_KALLSYMS 選項。此外,還可以啓用 CONFIG_DEBUG_KERNEL 和
 CONFIG_DEBUG_INFO;後者是相關選項,但只有啓用前者才能開啓。請注意,
 CONFIG_DEBUG_INFO 會需要更多儲存空間來構建內核。但這是值得的,因爲這些選項將
-允許您稍後精確定位觸發問題的確切代碼行。下面的「解碼失敗信息」一節對此進行了更
+允許您稍後精確定位觸發問題的確切代碼行。下面的“解碼失敗信息”一節對此進行了更
 詳細的解釋。
 
 但請記住:始終記錄遇到的問題,以防難以重現。發送未解碼的報告總比不報告要好。
 
 
-檢查「汙染」標誌
+檢查“污染”標誌
 ----------------
 
-    *確保您剛剛安裝的內核在運行時不會「汙染」自己。*
+    *確保您剛剛安裝的內核在運行時不會“污染”自己。*
 
 正如上面已經詳細介紹過的:當發生一些可能會導致一些看起來完全不相關的後續錯
-誤的事情時,內核會設置一個「汙染」標誌。這就是爲什麼你需要檢查你剛剛安裝的內
+誤的事情時,內核會設置一個“污染”標誌。這就是爲什麼你需要檢查你剛剛安裝的內
 核是否有設置此標誌。如果有的話,幾乎在任何情況下你都需要在報告問題之前先消
 除它。詳細的操作方法請看上面的章節。
 
@@ -729,43 +724,43 @@ CONFIG_DEBUG_INFO 會需要更多儲存空間來構建內核。但這是值得
 可以考慮使用此版本線,放棄報告問題。但是請記住,只要它沒有在 `kernel.org
 <https://kernel.org/>`_ 的穩定版和長期版(以及由這些版本衍生出來的廠商內核)
 中得到修復,其他用戶可能仍然會受到它的困擾。如果你喜歡使用其中的一個,或
-者只是想幫助它們的用戶,請前往下面的「報告只發生在較舊內核版本線的問題」一節。
+者只是想幫助它們的用戶,請前往下面的“報告只發生在較舊內核版本線的問題”一節。
 
 
 優化復現問題的描述
 --------------------
 
-    *優化你的筆記:試著找到並寫出最直接的復現問題的方法。確保最終結果包含所
+    *優化你的筆記:試着找到並寫出最直接的復現問題的方法。確保最終結果包含所
     有重要的細節,同時讓第一次聽說的人容易閱讀和理解。如果您在此過程中學到
     了一些東西,請考慮再次搜索關於該問題的現有報告。*
 
 過於複雜的報告會讓別人很難理解。因此請儘量找到一個可以直接描述、易於以書面
 形式理解的再現方法。包含所有重要的細節,但同時也要儘量保持簡短。
 
-在這在前面的步驟中,你很可能已經了解了一些關於你所面臨的問題的點。利用這些
+在這在前面的步驟中,你很可能已經瞭解了一些關於你所面臨的問題的點。利用這些
 知識,再次搜索可以轉而加入的現有報告。
 
 
 解碼失敗信息
 -------------
 
-    *如果失敗涉及「panic」、「Oops」、「warning」或「BUG」,請考慮解碼內核日誌以查找
+    *如果失敗涉及“panic”、“Oops”、“warning”或“BUG”,請考慮解碼內核日誌以查找
     觸發錯誤的代碼行。*
 
-當內核檢測到內部問題時,它會記錄一些有關已執行代碼的信息。這使得在原始碼中精
+當內核檢測到內部問題時,它會記錄一些有關已執行代碼的信息。這使得在源代碼中精
 確定位觸發問題的行並顯示如何調用它成爲可能。但只有在配置內核時啓用了
 CONFIG_DEBUG_INFO 和 CONFIG_KALLSYMS選項時,這種方法才起效。如果已啓用此選項,
-請考慮解碼內核日誌中的信息。這將使我們更容易理解是什麼導致了「panic」、「Oops」、
-「warning」或「BUG」,從而增加了有人提供修復的機率。
+請考慮解碼內核日誌中的信息。這將使我們更容易理解是什麼導致了“panic”、“Oops”、
+“warning”或“BUG”,從而增加了有人提供修復的幾率。
 
-解碼可以通過Linux原始碼樹中的腳本來完成。如果您運行的內核是之前自己編譯的,
+解碼可以通過Linux源代碼樹中的腳本來完成。如果您運行的內核是之前自己編譯的,
 這樣這樣調用它::
 
 	[user@something ~]$ sudo dmesg | ./linux-5.10.5/scripts/decode_stacktrace.sh ./linux-5.10.5/vmlinux
 	/usr/lib/debug/lib/modules/5.10.10-4.1.x86_64/vmlinux /usr/src/kernels/5.10.10-4.1.x86_64/
 
 如果您運行的是打包好的普通內核,則可能需要安裝帶有調試符號的相應包。然後按以下
-方式調用腳本(如果發行版未打包,則可能需要從Linux原始碼獲取)::
+方式調用腳本(如果發行版未打包,則可能需要從Linux源代碼獲取)::
 
 	[user@something ~]$ sudo dmesg | ./linux-5.10.5/scripts/decode_stacktrace.sh \
 	/usr/lib/debug/lib/modules/5.10.10-4.1.x86_64/vmlinux /usr/src/kernels/5.10.10-4.1.x86_64/
@@ -778,10 +773,10 @@ CONFIG_DEBUG_INFO 和 CONFIG_KALLSYMS選項時,這種方法才起效。如果
 
 	[   68.387301] RIP: 0010:test_module_init (/home/username/linux-5.10.5/test-module/test-module.c:16) test_module
 
-在本例中,執行的代碼是從文件「~/linux-5.10.5/test-module/test-module.c」構建的,
+在本例中,執行的代碼是從文件“~/linux-5.10.5/test-module/test-module.c”構建的,
 錯誤出現在第16行的指令中。
 
-該腳本也會如此解碼以「Call trace」開頭的部分中提到的地址,該部分顯示出現問題的
+該腳本也會如此解碼以“Call trace”開頭的部分中提到的地址,該部分顯示出現問題的
 函數的路徑。此外,腳本還會顯示內核正在執行的代碼部分的彙編輸出。
 
 注意,如果你沒法做到這一點,只需跳過這一步,並在報告中說明原因。如果你幸運的
@@ -790,60 +785,60 @@ CONFIG_DEBUG_INFO 和 CONFIG_KALLSYMS選項時,這種方法才起效。如果
 別擔心,如果您碰到的情況需要這樣做,開發人員會告訴您該怎麼做。
 
 
-對回歸的特別關照
+對迴歸的特別關照
 -----------------
 
-    *如果您的問題是回歸問題,請儘可能縮小引入問題時的範圍。*
+    *如果您的問題是迴歸問題,請儘可能縮小引入問題時的範圍。*
 
 Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這就是爲什麼他
-認爲回歸是不可接受的,並希望看到它們被迅速修復。這就是爲什麼引入了回歸的改
-動導致的問題若無法通過其他方式快速解決,通常會被迅速撤銷。因此,報告回歸有
-點像「王炸」,會迅速得到修復。但要做到這一點,需要知道導致回歸的變化。通常情
+認爲迴歸是不可接受的,並希望看到它們被迅速修復。這就是爲什麼引入了迴歸的改
+動導致的問題若無法通過其他方式快速解決,通常會被迅速撤銷。因此,報告迴歸有
+點像“王炸”,會迅速得到修復。但要做到這一點,需要知道導致迴歸的變化。通常情
 況下,要由報告者來追查罪魁禍首,因爲維護者往往沒有時間或手頭設置不便來自行
 重現它。
 
-有一個叫做「二分」的過程可以來尋找變化,這在
-「Documentation/translations/zh_TW/admin-guide/bug-bisect.rst」文檔中進行了詳細
+有一個叫做“二分”的過程可以來尋找變化,這在
+Documentation/translations/zh_CN/admin-guide/bug-bisect.rst 文檔中進行了詳細
 的描述,這個過程通常需要你構建十到二十個內核鏡像,每次都嘗試在構建下一個鏡像
-之前重現問題。是的,這需要花費一些時間,但不用擔心,它比大多數人想像的要快得多。
-多虧了「binary search二進位搜索」,這將引導你在原始碼管理系統中找到導致回歸的提交。
+之前重現問題。是的,這需要花費一些時間,但不用擔心,它比大多數人想象的要快得多。
+多虧了“binary search二分搜索”,這將引導你在源代碼管理系統中找到導致迴歸的提交。
 一旦你找到它,就在網上搜索其主題、提交ID和縮短的提交ID(提交ID的前12個字符)。
 如果有的話,這將引導您找到關於它的現有報告。
 
 需要注意的是,二分法需要一點竅門,不是每個人都懂得訣竅,也需要相當多的努力,
 不是每個人都願意投入。儘管如此,還是強烈建議自己進行一次二分。如果你真的
-不能或者不想走這條路,至少要找出是哪個主線內核引入的回歸。比如說從 5.5.15
+不能或者不想走這條路,至少要找出是哪個主線內核引入的迴歸。比如說從 5.5.15
 切換到 5.8.4 的時候出現了一些問題,那麼至少可以嘗試一下相近的所有的主線版本
 (5.6、5.7 和 5.8)來檢查它是什麼時候出現的。除非你想在一個穩定版或長期支持
-內核中找到一個回歸,否則要避免測試那些編號有三段的版本(5.6.12、5.7.8),因
-爲那會使結果難以解釋,可能會讓你的測試變得無用。一旦你找到了引入回歸的主要
+內核中找到一個迴歸,否則要避免測試那些編號有三段的版本(5.6.12、5.7.8),因
+爲那會使結果難以解釋,可能會讓你的測試變得無用。一旦你找到了引入迴歸的主要
 版本,就可以放心地繼續報告了。但請記住:在不知道罪魁禍首的情況下,開發人員
 是否能夠提供幫助取決於手頭的問題。有時他們可能會從報告中確認是什麼出現了問
 題,並能修復它;有時他們可能無法提供幫助,除非你進行二分。
 
-當處理回歸問題時,請確保你所面臨的問題真的是由內核引起的,而不是由其他東西
+當處理迴歸問題時,請確保你所面臨的問題真的是由內核引起的,而不是由其他東西
 引起的,如上文所述。
 
-在整個過程中,請記住:只有當舊內核和新內核的配置相似時,問題才算回歸。最好
-的方法是:把配置文件(``.config``)從舊的工作內核直接複製到你嘗試的每個新內
-核版本。之後運行 ``make oldnoconfig`` 來調整它以適應新版本的需要,而不啓用
-任何新的功能,因爲那些功能也可能導致回歸。
+在整個過程中,請記住:只有當舊內核和新內核的配置相似時,問題纔算迴歸。這可以
+通過 ``make olddefconfig`` 來實現,詳細解釋參見
+Documentation/admin-guide/reporting-regressions.rst ;它還提供了大量其他您
+可能希望瞭解的有關回歸的信息。
 
 
-撰寫並發送報告
+撰寫併發送報告
 ---------------
 
     *通過詳細描述問題來開始編寫報告。記得包括以下條目:您爲復現而安裝的最新
     內核版本、使用的Linux發行版以及關於如何復現該問題的說明。如果可能,將內
-    核構建配置(.config)和 ``dmesg`` 的輸出放在網上的某個地方,並連結到它。
+    核構建配置(.config)和 ``dmesg`` 的輸出放在網上的某個地方,並鏈接到它。
     包含或上傳所有其他可能相關的信息,如Oops的輸出/截圖或來自 ``lspci``
     的輸出。一旦你寫完了這個主要部分,請在上方插入一個正常長度的段落快速概
     述問題和影響。再在此之上添加一個簡單描述問題的句子,以得到人們的閱讀。
     現在給出一個更短的描述性標題或主題。然後就可以像MAINTAINERS文件告訴你的
-    那樣發送或提交報告了,除非你在處理一個「高優先級問題」:它們需要按照下面
-    「高優先級問題的特殊處理」所述特別關照。*
+    那樣發送或提交報告了,除非你在處理一個“高優先級問題”:它們需要按照下面
+    “高優先級問題的特殊處理”所述特別關照。*
 
-現在你已經準備好了一切,是時候寫你的報告了。上文前言中連結的三篇文檔對如何
+現在你已經準備好了一切,是時候寫你的報告了。上文前言中鏈接的三篇文檔對如何
 寫報告做了部分解釋。這就是爲什麼本文將只提到一些基本的內容以及 Linux 內核特
 有的東西。
 
@@ -855,7 +850,7 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 每份報告都應提及的事項
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
-詳細描述你的問題是如何發生在你安裝的新純淨內核上的。試著包含你之前寫的和優
+詳細描述你的問題是如何發生在你安裝的新純淨內核上的。試着包含你之前寫的和優
 化過的分步說明,概述你和其他人如何重現這個問題;在極少數無法重現的情況下,
 儘量描述你做了什麼來觸發它。
 
@@ -864,19 +859,19 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 
  * ``cat /proc/version`` 的輸出,其中包含 Linux 內核版本號和構建時的編譯器。
 
- * 機器正在運行的 Linux 發行版( ``hostnamectl | grep 「Operating System「`` )
+ * 機器正在運行的 Linux 發行版( ``hostnamectl | grep “Operating System“`` )
 
- * CPU 和作業系統的架構( ``uname -mi`` )
+ * CPU 和操作系統的架構( ``uname -mi`` )
 
- * 如果您正在處理回歸,並進行了二分,請提及導致回歸的變更的主題和提交ID。
+ * 如果您正在處理迴歸,並進行了二分,請提及導致迴歸的變更的主題和提交ID。
 
-許多情況下,讓讀你報告的人多了解兩件事也是明智之舉:
+許多情況下,讓讀你報告的人多瞭解兩件事也是明智之舉:
 
- * 用於構建 Linux 內核的配置(「.config」文件)
+ * 用於構建 Linux 內核的配置(“.config”文件)
 
- * 內核的信息,你從 ``dmesg`` 得到的信息寫到一個文件里。確保它以像「Linux
+ * 內核的信息,你從 ``dmesg`` 得到的信息寫到一個文件裏。確保它以像“Linux
    version 5.8-1 (foobar@example.com) (gcc (GCC) 10.2.1, GNU ld version
-   2.34) #1 SMP Mon Aug 3 14:54:37 UTC 2020」這樣的行開始,如果沒有,那麼第
+   2.34) #1 SMP Mon Aug 3 14:54:37 UTC 2020”這樣的行開始,如果沒有,那麼第
    一次啓動階段的重要信息已經被丟棄了。在這種情況下,可以考慮使用
    ``journalctl -b 0 -k`` ;或者你也可以重啓,重現這個問題,然後調用
    ``dmesg`` 。
@@ -887,39 +882,39 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 
  * 將文件上傳到某個公開的地方(你的網站,公共文件粘貼服務,在
    `bugzilla.kernel.org <https://bugzilla.kernel.org/>`_ 上創建的工單……),
-   並在你的報告中放上連結。理想情況下請使用允許這些文件保存很多年的地方,因
+   並在你的報告中放上鍊接。理想情況下請使用允許這些文件保存很多年的地方,因
    爲它們可能在很多年後對別人有用;例如 5 年或 10 年後,一個開發者正在修改
    一些代碼,而這些代碼正是爲了修復你的問題。
 
- * 把文件放在一邊,然後說明你會在他人回復時再單獨發送。只要記得報告發出去後,
+ * 把文件放在一邊,然後說明你會在他人回覆時再單獨發送。只要記得報告發出去後,
    真正做到這一點就可以了。;-)
 
 提供這些東西可能是明智的
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-根據問題的不同,你可能需要提供更多的背景數據。這裡有一些關於提供什麼比較好
+根據問題的不同,你可能需要提供更多的背景數據。這裏有一些關於提供什麼比較好
 的建議:
 
- * 如果你處理的是內核的「warning」、「OOPS」或「panic」,請包含它。如果你不能複製
-   粘貼它,試著用netconsole網絡終端遠程跟蹤或者至少拍一張屏幕的照片。
+ * 如果你處理的是內核的“warning”、“OOPS”或“panic”,請包含它。如果你不能複製
+   粘貼它,試着用netconsole網絡終端遠程跟蹤或者至少拍一張屏幕的照片。
 
- * 如果問題可能與你的電腦硬體有關,請說明你使用的是什麼系統。例如,如果你的
-   顯卡有問題,請提及它的製造商,顯卡的型號,以及使用的晶片。如果是筆記本電
-   腦,請提及它的型號名稱,但儘量確保意義明確。例如「戴爾 XPS 13」就不很明確,
+ * 如果問題可能與你的電腦硬件有關,請說明你使用的是什麼系統。例如,如果你的
+   顯卡有問題,請提及它的製造商,顯卡的型號,以及使用的芯片。如果是筆記本電
+   腦,請提及它的型號名稱,但儘量確保意義明確。例如“戴爾 XPS 13”就不很明確,
    因爲它可能是 2012 年的那款,那款除了看起來和現在銷售的沒有什麼不同之外,
    兩者沒有任何共同之處。因此,在這種情況下,要加上準確的型號,例如 2019
-   年內推出的 XPS 13 型號爲「9380」或「7390」。像「聯想 Thinkpad T590」這樣的名字
+   年內推出的 XPS 13 型號爲“9380”或“7390”。像“聯想 Thinkpad T590”這樣的名字
    也有些含糊不清:這款筆記本有帶獨立顯卡和不帶的子型號,所以要儘量找到準確
    的型號名稱或註明主要部件。
 
- * 說明正在使用的相關軟體。如果你在加載模塊時遇到了問題,你要說明正在使用的
+ * 說明正在使用的相關軟件。如果你在加載模塊時遇到了問題,你要說明正在使用的
    kmod、systemd 和 udev 的版本。如果其中一個 DRM 驅動出現問題,你要說明
    libdrm 和 Mesa 的版本;還要說明你的 Wayland 合成器或 X-Server 及其驅動。
    如果你有文件系統問題,請註明相應的文件系統實用程序的版本(e2fsprogs,
    btrfs-progs, xfsprogs……)。
 
  * 從內核中收集可能有用的額外信息。例如, ``lspci -nn`` 的輸出可以幫助別人
-   識別你使用的硬體。如果你的硬體有問題,你甚至可以給出 ``sudo lspci -vvv``
+   識別你使用的硬件。如果你的硬件有問題,你甚至可以給出 ``sudo lspci -vvv``
    的結果,因爲它提供了組件是如何配置的信息。對於一些問題,可能最好包含
    ``/proc/cpuinfo`` , ``/proc/ioports`` , ``/proc/iomem`` ,
    ``/proc/modules`` 或 ``/proc/scsi/scsi`` 等文件的內容。一些子系統還提
@@ -936,7 +931,7 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 ~~~~~~~~~~~~~~~~~~~~~~
 
 現在你已經準備好了報告的詳細部分,讓我們進入最重要的部分:開頭幾句。現在到
-報告的最前面,在你剛才寫的部分之前加上類似「The detailed description:」(詳細
+報告的最前面,在你剛纔寫的部分之前加上類似“The detailed description:”(詳細
 描述)這樣的內容,並在最前面插入兩個新行。現在寫一個正常長度的段落,大致概
 述這個問題。去掉所有枯燥的細節,把重點放在讀者需要知道的關鍵部分,以讓人了
 解這是怎麼回事;如果你認爲這個缺陷影響了很多用戶,就提一下這點來吸引大家關
@@ -946,10 +941,10 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 要更加抽象,爲報告寫一個更短的主題/標題。
 
 現在你已經寫好了這部分,請花點時間來優化它,因爲它是你的報告中最重要的部分:
-很多人會先讀這部分,然後才會決定是否值得花時間閱讀其他部分。
+很多人會先讀這部分,然後纔會決定是否值得花時間閱讀其他部分。
 
 現在就像 :ref:`MAINTAINERS <maintainers>` 維護者文件告訴你的那樣發送或提交
-報告,除非它是前面概述的那些「高優先級問題」之一:在這種情況下,請先閱讀下一
+報告,除非它是前面概述的那些“高優先級問題”之一:在這種情況下,請先閱讀下一
 小節,然後再發送報告。
 
 高優先級問題的特殊處理
@@ -960,11 +955,19 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 **非常嚴重的缺陷** :確保在主題或工單標題以及第一段中明顯標出 severeness
 (非常嚴重的)。
 
-**回歸** :如果問題是一個回歸,請在郵件的主題或缺陷跟蹤器的標題中添加
-[REGRESSION]。如果您沒有進行二分,請至少註明您測試的最新主線版本(比如 5.7)
-和出現問題的最新版本(比如 5.8)。如果您成功地進行了二分,請註明導致回歸
-的提交ID和主題。也請添加該變更的作者到你的報告中;如果您需要將您的缺陷提交
-到缺陷跟蹤器中,請將報告以私人郵件的形式轉發給他,並註明報告提交地點。
+**迴歸** :報告的主題應以“[REGRESSION]”開頭。
+
+如果您成功用二分法定位了問題,請使用引入迴歸之更改的標題作爲主題的第二部分。
+請在報告中寫明“罪魁禍首”的提交ID。如果未能成功二分,請在報告中講明最後一個
+正常工作的版本(例如5.7)和最先發生問題的版本(例如5.8-rc1)。
+
+通過郵件發送報告時,請抄送Linux迴歸郵件列表(regressions@lists.linux.dev)。
+如果報告需要提交到某個web追蹤器,請繼續提交;並在提交後,通過郵件將報告轉發
+至迴歸列表;抄送相關子系統的維護人員和郵件列表。請確保報告是內聯轉發的,不要
+把它作爲附件。另外請在頂部添加一個簡短的說明,在那裏寫上工單的網址。
+
+在郵寄或轉發報告時,如果成功二分,需要將“罪魁禍首”的作者添加到收件人中;同時
+抄送signed-off-by鏈中的每個人,您可以在提交消息的末尾找到。
 
 **安全問題** :對於這種問題,你將必須評估:如果細節被公開披露,是否會對其他
 用戶產生短期風險。如果不會,只需按照所述繼續報告問題。如果有此風險,你需要
@@ -972,47 +975,47 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 
  * 如果 MAINTAINERS 文件指示您通過郵件報告問題,請不要抄送任何公共郵件列表。
 
- * 如果你應該在缺陷跟蹤器中提交問題,請確保將工單標記爲「私有」或「安全問題」。
+ * 如果你應該在缺陷跟蹤器中提交問題,請確保將工單標記爲“私有”或“安全問題”。
    如果缺陷跟蹤器沒有提供保持報告私密性的方法,那就別想了,把你的報告以私人
    郵件的形式發送給維護者吧。
 
-在這兩種情況下,都一定要將報告發到 MAINTAINERS 文件中「安全聯絡」部分列出的
+在這兩種情況下,都一定要將報告發到 MAINTAINERS 文件中“安全聯絡”部分列出的
 地址。理想的情況是在發送報告的時候直接抄送他們。如果您在缺陷跟蹤器中提交了
-報告,請將報告的文本轉發到這些地址;但請在報告的頂部加上注釋,表明您提交了
-報告,並附上工單連結。
+報告,請將報告的文本轉發到這些地址;但請在報告的頂部加上註釋,表明您提交了
+報告,並附上工單鏈接。
 
-更多信息請參見「Documentation/translations/zh_TW/admin-guide/security-bugs.rst」。
+更多信息請參見 Documentation/translations/zh_CN/admin-guide/security-bugs.rst 。
 
 
-發布報告後的責任
+發佈報告後的責任
 ------------------
 
     *等待別人的反應,繼續推進事情,直到你能夠接受這樣或那樣的結果。因此,請
     公開和及時地回應任何詢問。測試提出的修復。積極地測試:至少重新測試每個
     新主線版本的首個候選版本(RC),並報告你的結果。如果出現拖延,就友好地
-    提醒一下。如果你沒有得到任何幫助或者未能滿意,請試著自己幫助自己。*
+    提醒一下。如果你沒有得到任何幫助或者未能滿意,請試着自己幫助自己。*
 
 如果你的報告非常優秀,而且你真的很幸運,那麼某個開發者可能會立即發現導致問
 題的原因;然後他們可能會寫一個補丁來修復、測試它,並直接發送給主線集成,同
-時標記它以便以後回溯到需要它的穩定版和長期支持內核。那麼你需要做的就是回復
-一句「Thank you very much」(非常感謝),然後在發布後換上修復好的版本。
+時標記它以便以後回溯到需要它的穩定版和長期支持內核。那麼你需要做的就是回覆
+一句“Thank you very much”(非常感謝),然後在發佈後換上修復好的版本。
 
-但這種理想狀況很少發生。這就是爲什麼你把報告拿出來之後工作才開始。你要做的
-事情要視情況而定,但通常會是下面列出的事情。但在深入研究細節之前,這裡有幾
+但這種理想狀況很少發生。這就是爲什麼你把報告拿出來之後工作纔開始。你要做的
+事情要視情況而定,但通常會是下面列出的事情。但在深入研究細節之前,這裏有幾
 件重要的事情,你需要記住這部分的過程。
 
 
 關於進一步互動的一般建議
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-**總是公開回復** :當你在缺陷跟蹤器中提交問題時,一定要在那裡回復,不要私下
-聯繫任何開發者。對於郵件報告,在回復您收到的任何郵件時,總是使用「全部回復」
+**總是公開回復** :當你在缺陷跟蹤器中提交問題時,一定要在那裏回覆,不要私下
+聯繫任何開發者。對於郵件報告,在回覆您收到的任何郵件時,總是使用“全部回覆”
 功能。這包括帶有任何你可能想要添加到你的報告中的額外數據的郵件:進入郵件應
-用程序「已發送」文件夾,並在郵件上使用「全部回復」來回復報告。這種方法可以確保
-公共郵件列表和其他所有參與者都能及時了解情況;它還能保持郵件線程的完整性,
+用程序“已發送”文件夾,並在郵件上使用“全部回覆”來回復報告。這種方法可以確保
+公共郵件列表和其他所有參與者都能及時瞭解情況;它還能保持郵件線程的完整性,
 這對於郵件列表將所有相關郵件歸爲一類是非常重要的。
 
-只有兩種情況不適合在缺陷跟蹤器或「全部回復」中發表評論:
+只有兩種情況不適合在缺陷跟蹤器或“全部回覆”中發表評論:
 
  * 有人讓你私下發東西。
 
@@ -1022,32 +1025,32 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 
 **在請求解釋或幫助之前先研究一下** :在這部分過程中,有人可能會告訴你用尚未
 掌握的技能做一些事情。例如你可能會被要求使用一些你從未聽說過的測試工具;或
-者你可能會被要求在 Linux 內核原始碼上應用一個補丁來測試它是否有幫助。在某些
-情況下,發個回復詢問如何做就可以了。但在走這條路之前,儘量通過在網際網路上搜
+者你可能會被要求在 Linux 內核源代碼上應用一個補丁來測試它是否有幫助。在某些
+情況下,發個回覆詢問如何做就可以了。但在走這條路之前,儘量通過在互聯網上搜
 索自行找到答案;或者考慮在其他地方詢問建議。比如詢問朋友,或者到你平時常去
 的聊天室或論壇發帖諮詢。
 
 **要有耐心** :如果你真的很幸運,你可能會在幾個小時內收到對你的報告的答覆。
 但大多數情況下會花費更多的時間,因爲維護者分散在全球各地,因此可能在不同的
-時區——在那裡他們已經享受著遠離鍵盤的夜晚。
+時區——在那裏他們已經享受着遠離鍵盤的夜晚。
 
 一般來說,內核開發者需要一到五個工作日來回復報告。有時會花費更長的時間,因
 爲他們可能正忙於合併窗口、其他工作、參加開發者會議,或者只是在享受一個漫長
 的暑假。
 
-「高優先級的問題」(見上面的解釋)例外:維護者應該儘快解決這些問題;這就是爲
+“高優先級的問題”(見上面的解釋)例外:維護者應該儘快解決這些問題;這就是爲
 什麼你應該最多等待一個星期(如果是緊急的事情,則只需兩天),然後再發送友好
 的提醒。
 
-有時維護者可能沒有及時回復;有時候可能會出現分歧,例如一個問題是否符合回歸
+有時維護者可能沒有及時回覆;有時候可能會出現分歧,例如一個問題是否符合迴歸
 的條件。在這種情況下,在郵件列表上提出你的顧慮,並請求其他人公開或私下回復
 如何繼續推進。如果失敗了,可能應該讓更高級別的維護者介入。如果是 WiFi 驅動,
 那就是無線維護者;如果沒有更高級別的維護者,或者其他一切努力都失敗了,那
 這可能是一種罕見的、可以讓 Linus Torvalds 參與進來的情況。
 
-**主動測試** :每當一個新的主線內核版本的第一個預發布版本(rc1)發布的時候,
+**主動測試** :每當一個新的主線內核版本的第一個預發佈版本(rc1)發佈的時候,
 去檢查一下這個問題是否得到了解決,或者是否有什麼重要的變化。在工單中或在
-回復報告的郵件中提及結果(確保所有參與討論的人都被抄送)。這將表明你的承諾
+回覆報告的郵件中提及結果(確保所有參與討論的人都被抄送)。這將表明你的承諾
 和你願意幫忙。如果問題持續存在,它也會提醒開發者確保他們不會忘記它。其他一
 些不定期的重新測試(例如用rc3、rc5 和最終版本)也是一個好主意,但只有在相關
 的東西發生變化或者你正在寫什麼東西的時候才報告你的結果。
@@ -1057,10 +1060,10 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 查詢和測試請求
 ~~~~~~~~~~~~~~~
 
-如果你的報告得到了回復則需履行以下責任:
+如果你的報告得到了回覆則需履行以下責任:
 
 **檢查與你打交道的人** :大多數情況下,會是維護者或特定代碼區域的開發人員對
-你的報告做出回應。但由於問題通常是公開報告的,所以回復的可能是任何人——包括
+你的報告做出回應。但由於問題通常是公開報告的,所以回覆的可能是任何人——包括
 那些想要幫忙的人,但最後可能會用他們的問題或請求引導你完全偏離軌道。這很少
 發生,但這是快速上網搜搜看你正在與誰互動是明智之舉的許多原因之一。通過這樣
 做,你也可以知道你的報告是否被正確的人聽到,因爲如果討論沒有導致滿意的問題
@@ -1086,63 +1089,63 @@ Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這
 報告到達時,維護者剛剛離開鍵盤一段時間,或者有更重要的事情要處理。在寫提醒
 信的時候,要善意地問一下,是否還需要你這邊提供什麼來讓事情推進下去。如果報
 告是通過郵件發出來的,那就在郵件的第一行回覆你的初始郵件(見上文),其中包
-括下方的原始報告的完整引用:這是少數幾種情況下,這樣的「TOFU」(Text Over,
+括下方的原始報告的完整引用:這是少數幾種情況下,這樣的“TOFU”(Text Over,
 Fullquote Under文字在上,完整引用在下)是正確的做法,因爲這樣所有的收件人都
 會以適當的順序立即讓細節到手頭上來。
 
-在提醒之後,再等三周的回覆。如果你仍然沒有得到適當的反饋,你首先應該重新考
+在提醒之後,再等三週的回覆。如果你仍然沒有得到適當的反饋,你首先應該重新考
 慮你的方法。你是否可能嘗試接觸了錯誤的人?是不是報告也許令人反感或者太混亂,
 以至於人們決定完全遠離它?排除這些因素的最好方法是:把報告給一兩個熟悉
 FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於如何繼續推進的建議。
-這可能意味著:準備一份更好的報告,讓這些人在你發出去之前對它進行審查。這樣
+這可能意味着:準備一份更好的報告,讓這些人在你發出去之前對它進行審查。這樣
 的方法完全可以;只需說明這是關於這個問題的第二份改進的報告,並附上第一份報
-告的連結。
+告的鏈接。
 
 如果報告是恰當的,你可以發送第二封提醒信;在其中詢問爲什麼報告沒有得到任何
-回復。第二封提醒郵件的好時機是在新 Linux 內核版本的首個預發布版本('rc1')
-發布後不久,因爲無論如何你都應該在那個時候重新測試並提供狀態更新(見上文)。
+回覆。第二封提醒郵件的好時機是在新 Linux 內核版本的首個預發佈版本('rc1')
+發佈後不久,因爲無論如何你都應該在那個時候重新測試並提供狀態更新(見上文)。
 
-如果第二次提醒的結果又在一周內沒有任何反應,可以嘗試聯繫上級維護者詢問意見:
+如果第二次提醒的結果又在一週內沒有任何反應,可以嘗試聯繫上級維護者詢問意見:
 即使再忙的維護者在這時候也至少應該發過某種確認。
 
 記住要做好失望的準備:理想狀況下維護者最好對每一個問題報告做出回應,但他們
-只有義務解決之前列出的「高優先級問題」。所以,如果你得到的回覆是「謝謝你的報告,
-我目前有更重要的問題要處理,在可預見的未來沒有時間去研究這個問題」,那請不
+只有義務解決之前列出的“高優先級問題”。所以,如果你得到的回覆是“謝謝你的報告,
+我目前有更重要的問題要處理,在可預見的未來沒有時間去研究這個問題”,那請不
 要太沮喪。
 
 也有可能在缺陷跟蹤器或列表中進行了一些討論之後,什麼都沒有發生,提醒也無助
 於激勵大家進行修復。這種情況可能是毀滅性的,但在 Linux 內核開發中確實會發生。
-這些和其他得不到幫助的原因在本文結尾處的「爲什麼有些問題在被報告後沒有得到
-任何回應或者仍然沒有修復」中進行了解釋。
+這些和其他得不到幫助的原因在本文結尾處的“爲什麼有些問題在被報告後沒有得到
+任何回應或者仍然沒有修復”中進行了解釋。
 
 如果你沒有得到任何幫助或問題最終沒有得到解決,不要沮喪:Linux 內核是 FLOSS,
-因此你仍然可以自己幫助自己。例如,你可以試著找到其他受影響的人,和他們一
+因此你仍然可以自己幫助自己。例如,你可以試着找到其他受影響的人,和他們一
 起合作來解決這個問題。這樣的團隊可以一起準備一份新的報告,提到團隊有多少人,
 爲什麼你們認爲這是應該得到解決的事情。也許你們還可以一起縮小確切原因或引
-入回歸的變化,這往往會使修復更容易。而且如果運氣好的話,團隊中可能會有懂點
-編程的人,也許能寫出一個修複方案。
+入迴歸的變化,這往往會使修復更容易。而且如果運氣好的話,團隊中可能會有懂點
+編程的人,也許能寫出一個修復方案。
 
 
 
-「報告穩定版和長期支持內核線的回歸」的參考
+“報告穩定版和長期支持內核線的迴歸”的參考
 ------------------------------------------
 
-本小節提供了在穩定版和長期支持內核線中面對回歸時需要執行的步驟的詳細信息。
+本小節提供了在穩定版和長期支持內核線中面對迴歸時需要執行的步驟的詳細信息。
 
 確保特定版本線仍然受支持
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
     *檢查內核開發人員是否仍然維護你關心的Linux內核版本線:去 kernel.org 的
-    首頁,確保此特定版本線的最新版沒有「[EOL]」標記。*
+    首頁,確保此特定版本線的最新版沒有“[EOL]”標記。*
 
 大多數內核版本線只支持三個月左右,因爲延長維護時間會帶來相當多的工作。因此,
 每年只會選擇一個版本來支持至少兩年(通常是六年)。這就是爲什麼你需要檢查
 內核開發者是否還支持你關心的版本線。
 
-注意,如果 `kernel.org <https://kernel.org/>`_ 在首頁上列出了兩個「穩定」版本,
+注意,如果 `kernel.org <https://kernel.org/>`_ 在首頁上列出了兩個“穩定”版本,
 你應該考慮切換到較新的版本,而忘掉較舊的版本:對它的支持可能很快就會結束。
-然後,它將被標記爲「生命周期結束」(EOL)。達到這個程度的版本線仍然會在
-`kernel.org <https://kernel.org/>`_ 首頁上被顯示一兩周,但不適合用於測試和
+然後,它將被標記爲“生命週期結束”(EOL)。達到這個程度的版本線仍然會在
+`kernel.org <https://kernel.org/>`_ 首頁上被顯示一兩週,但不適合用於測試和
 報告。
 
 搜索穩定版郵件列表
@@ -1158,57 +1161,63 @@ FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於
 用最新版本復現問題
 ~~~~~~~~~~~~~~~~~~~
 
-    *從特定的版本線安裝最新版本作爲純淨內核。確保這個內核沒有被汙染,並且仍
-    然存在問題,因爲問題可能已經在那裡被修復了。*
+    *從特定的版本線安裝最新版本作爲純淨內核。確保這個內核沒有被污染,並且仍
+    然存在問題,因爲問題可能已經在那裏被修復了。*
 
 在投入更多時間到這個過程中之前,你要檢查這個問題是否在你關注的版本線的最新
-版本中已經得到了修復。這個內核需要是純淨的,在問題發生之前不應該被汙染,正
+版本中已經得到了修復。這個內核需要是純淨的,在問題發生之前不應該被污染,正
 如上面已經在測試主線的過程中詳細介紹過的一樣。
 
-您是否是第一次注意到供應商內核的回歸?供應商的更改可能會發生變化。你需要重新
+您是否是第一次注意到供應商內核的迴歸?供應商的更改可能會發生變化。你需要重新
 檢查排除來這個問題。當您從5.10.4-vendor.42更新到5.10.5-vendor.43時,記錄損壞
 的信息。然後在測試了前一段中所述的最新5.10版本之後,檢查Linux 5.10.4的普通版本
-是否也可以正常工作。如果問題在那裡出現,那就不符合上游回歸的條件,您需要切換
+是否也可以正常工作。如果問題在那裏出現,那就不符合上游迴歸的條件,您需要切換
 回主逐步指南來報告問題。
 
-報告回歸
+報告迴歸
 ~~~~~~~~~~
 
-    *向Linux穩定版郵件列表發送一個簡短的問題報告(stable@vger.kernel.org)。
-    大致描述問題,並解釋如何復現。講清楚首個出現問題的版本和最後一個工作正常
-    的版本。然後等待進一步的指示。*
+    *向Linux穩定版郵件列表發送一個簡短的問題報告(stable@vger.kernel.org)並
+    抄送Linux迴歸郵件列表(regressions@lists.linux.dev);如果你懷疑是由某
+    子系統引起的,請抄送其維護人員和子系統郵件列表。大致描述問題,並解釋如
+    何復現。講清楚首個出現問題的版本和最後一個工作正常的版本。然後等待進一
+    步的指示。*
 
-當報告在穩定版或長期支持內核線內發生的回歸(例如在從5.10.4更新到5.10.5時),
-一份簡短的報告足以快速報告問題。因此只需要粗略的描述。
+當報告在穩定版或長期支持內核線內發生的迴歸(例如在從5.10.4更新到5.10.5時),
+一份簡短的報告足以快速報告問題。因此只需向穩定版和迴歸郵件列表發送粗略的描述;
+不過如果你懷疑某子系統導致此問題的話,請一併抄送其維護人員和子系統郵件列表,
+這會加快進程。
 
-但是請注意,如果您能夠指明引入問題的確切版本,這將對開發人員有很大幫助。因此
-如果有時間的話,請嘗試使用普通內核找到該版本。讓我們假設發行版發布Linux內核
+請注意,如果您能夠指明引入問題的確切版本,這將對開發人員有很大幫助。因此
+如果有時間的話,請嘗試使用普通內核找到該版本。讓我們假設發行版發佈Linux內核
 5.10.5到5.10.8的更新時發生了故障。那麼按照上面的指示,去檢查該版本線中的最新
 內核,比如5.10.9。如果問題出現,請嘗試普通5.10.5,以確保供應商應用的補丁不會
 干擾。如果問題沒有出現,那麼嘗試5.10.7,然後直到5.10.8或5.10.6(取決於結果)
 找到第一個引入問題的版本。在報告中寫明這一點,並指出5.10.9仍然存在故障。
 
-前一段基本粗略地概述了「二分」方法。一旦報告出來,您可能會被要求做一個正確的
+前一段基本粗略地概述了“二分”方法。一旦報告出來,您可能會被要求做一個正確的
 報告,因爲它允許精確地定位導致問題的確切更改(然後很容易被恢復以快速修復問題)。
-因此如果時間允許,考慮立即進行適當的二分。有關如何詳細信息,請參閱「對回歸的
-特別關照」部分和文檔「Documentation/translations/zh_TW/admin-guide/bug-bisect.rst」。
+因此如果時間允許,考慮立即進行適當的二分。有關如何詳細信息,請參閱“對迴歸的
+特別關照”部分和文檔 Documentation/translations/zh_CN/admin-guide/bug-bisect.rst 。
+如果成功二分的話,請將“罪魁禍首”的作者添加到收件人中;同時抄送所有在
+signed-off-by鏈中的人,您可以在提交消息的末尾找到。
 
 
-「報告僅在舊內核版本線中發生的問題」的參考
-------------------------------------------
+“報告僅在舊內核版本線中發生的問題”的參考
+----------------------------------------
 
-本節詳細介紹了如果無法用主線內核重現問題,但希望在舊版本線(又稱穩定版內核和
+本節詳細介紹瞭如果無法用主線內核重現問題,但希望在舊版本線(又稱穩定版內核和
 長期支持內核)中修復問題時需要採取的步驟。
 
 有些修復太複雜
 ~~~~~~~~~~~~~~~
 
     *請做好準備,接下來的幾個步驟可能無法在舊版本中解決問題:修復可能太大或
-    太冒險,無法移植到那裡。*
+    太冒險,無法移植到那裏。*
 
 即使是微小的、看似明顯的代碼變化,有時也會帶來新的、完全意想不到的問題。穩
 定版和長期支持內核的維護者非常清楚這一點,因此他們只對這些內核進行符合
-「Documentation/translations/zh_TW/process/stable-kernel-rules.rst」中所列出的
+Documentation/translations/zh_CN/process/stable-kernel-rules.rst 中所列出的
 規則的修改。
 
 複雜或有風險的修改不符合條件,因此只能應用於主線。其他的修復很容易被回溯到
@@ -1220,7 +1229,7 @@ FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於
 通用準備
 ~~~~~~~~~~
 
-    *執行上面「報告僅在舊內核版本線中發生的問題」一節中的前三個步驟。*
+    *執行上面“報告僅在舊內核版本線中發生的問題”一節中的前三個步驟。*
 
 您需要執行本指南另一節中已經描述的幾個步驟。這些步驟將讓您:
 
@@ -1242,21 +1251,21 @@ FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於
 在許多情況下,你所處理的問題會發生在主線上,但已在主線上得到了解決。修正它
 的提交也需要被回溯才能解決這個問題。這就是爲什麼你要搜索它或任何相關討論。
 
- * 首先嘗試在存放 Linux 內核原始碼的 Git 倉庫中找到修復。你可以通過
+ * 首先嚐試在存放 Linux 內核源代碼的 Git 倉庫中找到修復。你可以通過
    `kernel.org 上的網頁
    <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/>`_
    或 `GitHub 上的鏡像 <https://github.com/torvalds/linux>`_ 來實現;如果你
    有一個本地克隆,你也可以在命令行用 ``git log --grep=<pattern>`` 來搜索。
 
-   如果你找到了修復,請查看提交消息的尾部是否包含了類似這樣的「穩定版標籤」:
+   如果你找到了修復,請查看提交消息的尾部是否包含了類似這樣的“穩定版標籤”:
 
           Cc: <stable@vger.kernel.org> # 5.4+
 
    像上面這行,開發者標記了安全修復可以回傳到 5.4 及以後的版本。大多數情況
-   下,它會在兩周內被應用到那裡,但有時需要更長的時間。
+   下,它會在兩週內被應用到那裏,但有時需要更長的時間。
 
  * 如果提交沒有告訴你任何東西,或者你找不到修復,請再找找關於這個問題的討論。
-   用你最喜歡的搜尋引擎搜索網絡,以及 `Linux kernel developers mailing
+   用你最喜歡的搜索引擎搜索網絡,以及 `Linux kernel developers mailing
    list 內核開發者郵件列表 <https://lore.kernel.org/lkml/>`_ 的檔案。也可以
    閱讀上面的 `定位導致問題的內核區域` 一節,然後按照說明找到導致問題的子系
    統:它的缺陷跟蹤器或郵件列表存檔中可能有你要找的答案。
@@ -1286,41 +1295,41 @@ FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於
 爲什麼有些問題在報告後沒有任何回應或仍未解決?
 ===============================================
 
-當向 Linux 開發者報告問題時,要注意只有「高優先級的問題」(回歸、安全問題、嚴
+當向 Linux 開發者報告問題時,要注意只有“高優先級的問題”(迴歸、安全問題、嚴
 重問題)才一定會得到解決。如果維護者或其他人都失敗了,Linus Torvalds 他自己
 會確保這一點。他們和其他內核開發者也會解決很多其他問題。但是要知道,有時他
 們也會不能或不願幫忙;有時甚至沒有人發報告給他們。
 
 最好的解釋就是那些內核開發者常常是在業餘時間爲 Linux 內核做出貢獻。內核中的
-不少驅動程序都是由這樣的程式設計師編寫的,往往只是因爲他們想讓自己的硬體可以在
-自己喜歡的作業系統上使用。
+不少驅動程序都是由這樣的程序員編寫的,往往只是因爲他們想讓自己的硬件可以在
+自己喜歡的操作系統上使用。
 
-這些程式設計師大多數時候會很樂意修復別人報告的問題。但是沒有人可以強迫他們這樣
+這些程序員大多數時候會很樂意修復別人報告的問題。但是沒有人可以強迫他們這樣
 做,因爲他們是自願貢獻的。
 
 還有一些情況下,這些開發者真的很想解決一個問題,但卻不能解決:有時他們缺乏
-硬體編程文檔來解決問題。這種情況往往由於公開的文檔太簡陋,或者驅動程序是通
+硬件編程文檔來解決問題。這種情況往往由於公開的文檔太簡陋,或者驅動程序是通
 過逆向工程編寫的。
 
-業餘開發者遲早也會不再關心某驅動。也許他們的測試硬體壞了,被更高級的玩意取
-代了,或者是太老了以至於只能在計算機博物館裡找到。有時開發者根本就不關心他
+業餘開發者遲早也會不再關心某驅動。也許他們的測試硬件壞了,被更高級的玩意取
+代了,或者是太老了以至於只能在計算機博物館裏找到。有時開發者根本就不關心他
 們的代碼和 Linux 了,因爲在他們的生活中一些不同的東西變得更重要了。在某些情
 況下,沒有人願意接手維護者的工作——也沒有人可以被強迫,因爲對 Linux 內核的貢
 獻是自願的。然而被遺棄的驅動程序仍然存在於內核中:它們對人們仍然有用,刪除
-它們可能導致回歸。
+它們可能導致迴歸。
 
 對於那些爲 Linux 內核工作而獲得報酬的開發者來說,情況並沒有什麼不同。這些人
 現在貢獻了大部分的變更。但是他們的僱主遲早也會停止關注他們的代碼或者讓程序
-員專注於其他事情。例如,硬體廠商主要通過銷售新硬體來賺錢;因此,他們中的不
+員專注於其他事情。例如,硬件廠商主要通過銷售新硬件來賺錢;因此,他們中的不
 少人並沒有投入太多時間和精力來維護他們多年前就停止銷售的東西的 Linux 內核驅
 動。企業級 Linux 發行商往往持續維護的時間比較長,但在新版本中往往會把對老舊
-和稀有硬體的支持放在一邊,以限制範圍。一旦公司拋棄了一些代碼,往往由業餘貢
+和稀有硬件的支持放在一邊,以限制範圍。一旦公司拋棄了一些代碼,往往由業餘貢
 獻者接手,但正如上面提到的:他們遲早也會放下代碼。
 
 優先級是一些問題沒有被修復的另一個原因,因爲維護者相當多的時候是被迫設置這
 些優先級的,因爲在 Linux 上工作的時間是有限的。對於業餘時間或者僱主給予他們
 的開發人員用於上游內核維護工作的時間也是如此。有時維護人員也會被報告淹沒,
-即使一個驅動程序幾乎完美地工作。爲了不被完全纏住,程式設計師可能別無選擇,只能
+即使一個驅動程序幾乎完美地工作。爲了不被完全纏住,程序員可能別無選擇,只能
 對問題報告進行優先級排序而拒絕其中的一些報告。
 
 不過這些都不用太過擔心,很多驅動都有積極的維護者,他們對儘可能多的解決問題
@@ -1330,8 +1339,32 @@ FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於
 結束語
 =======
 
-與其他免費/自由&開源軟體(Free/Libre & Open Source Software,FLOSS)相比,
-向 Linux 內核開發者報告問題是很難的:這個文檔的長度和複雜性以及字裡行間的內
+與其他免費/自由&開源軟件(Free/Libre & Open Source Software,FLOSS)相比,
+向 Linux 內核開發者報告問題是很難的:這個文檔的長度和複雜性以及字裏行間的內
 涵都說明了這一點。但目前就是這樣了。這篇文字的主要作者希望通過記錄現狀來爲
 以後改善這種狀況打下一些基礎。
 
+
+..
+   end-of-content
+..
+   This English version of this document is maintained by Thorsten Leemhuis
+   <linux@leemhuis.info>. If you spot a typo or small mistake, feel free to
+   let him know directly and he'll fix it. For translation problems, please
+   contact with translators. You are free to do the same in a mostly informal
+   way if you want to contribute changes to the text, but for copyright
+   reasons please CC linux-doc@vger.kernel.org and "sign-off" your
+   contribution as Documentation/process/submitting-patches.rst outlines in
+   the section "Sign your work - the Developer's Certificate of Origin".
+..
+   This text is available under GPL-2.0+ or CC-BY-4.0, as stated at the top
+   of the file. If you want to distribute this text under CC-BY-4.0 only,
+   please use "The Linux kernel developers" for author attribution and link
+   this as source:
+   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/reporting-issues.rst
+..
+   Note: Only the content of this RST file as found in the Linux kernel sources
+   is available under CC-BY-4.0, as versions of this text that were processed
+   (for example by the kernel's build system) might contain content taken from
+   files which use a more restrictive license.
+
diff --git a/Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst b/Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst
new file mode 100644
index 000000000000..d7dcb2a26564
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/reporting-regressions.rst
@@ -0,0 +1,371 @@
+.. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0)
+.. 【重分發信息參見本文件結尾】
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/reporting-regressions.rst
+
+:譯者:
+
+ 吳想成 Wu XiangCheng <bobwxc@email.cn>
+
+
+============
+報告迴歸問題
+============
+
+“*我們拒絕出現迴歸*”是Linux內核開發的首要規則;Linux的發起者和領軍開發者Linus
+Torvalds立下了此規則並確保它被落實。
+
+本文檔描述了這條規則對用戶的意義,以及Linux內核開發模型如何確保解決所有被報告
+的迴歸;關於內核開發者如何處理的方面參見 Documentation/process/handling-regressions.rst 。
+
+
+本文重點(亦即“太長不看”)
+==========================
+
+#. 如果某程序在原先的Linux內核上運行良好,但在較新版本上效果更差、或者根本不
+   能用,那麼你就碰見迴歸問題了。注意,新內核需要使用類似配置編譯;更多相關細
+   節參見下方。
+
+#. 按照 Documentation/translations/zh_CN/admin-guide/reporting-issues.rst 中
+   所說的報告你的問題,該文檔已經包含了所有關於迴歸的重要方面,爲了方便起見也
+   複製到了下面。兩個重點:在報告主題中使用“[REGRESSION]”開頭並抄送或轉發到
+   `迴歸郵件列表 <https://lore.kernel.org/regressions/>`_
+   (regressions@lists.linux.dev)。
+
+#. 可選但是建議:在發送或轉發報告時,指明該回歸發生的起點,以便Linux內核迴歸
+   追蹤機器人“regzbot”可以追蹤此問題::
+
+       #regzbot introduced v5.13..v5.14-rc1
+
+
+與用戶相關的所有Linux內核迴歸細節
+=================================
+
+
+基本重點
+--------
+
+
+什麼是“迴歸”以及什麼是“無迴歸規則”?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+如果某程序/實例在原先的Linux內核上運行良好,但在較新版本上效果更差、或者根本
+不能用,那麼你就碰見迴歸問題了。“無迴歸規則”不允許出現這種情況。如果偶然發
+生了,導致問題的開發者應當迅速修復問題。
+
+也就是說,若Linux 5.13中的WiFi驅動程序運行良好,但是在5.14版本上卻不能用、速
+度明顯變慢或出現錯誤,那就出現了迴歸。如果某正常工作的應用程序突然在新內核上
+出現不穩定,這也是迴歸;這些問題可能是由於procfs、sysfs或Linux提供給用戶空間
+軟件的許多其他接口之一的變化。但請記住,前述例子中的5.14需要使用類似於5.13的
+配置構建。這可以用 ``make olddefconfig`` 實現,詳細解釋見下。
+
+注意本節第一句話中的“實例”:即使開發者需要遵循“無迴歸”規則,但仍可自由地改
+變內核的任何方面,甚至是導出到用戶空間的API或ABI,只要別破壞現有的應用程序或
+用例。
+
+還需注意,“無迴歸”規則只限制內核提供給用戶空間的接口。它不適用於內核內部接
+口,比如一些外部開發的驅動程序用來插入鉤子到內核的模塊API。
+
+如何報告迴歸?
+~~~~~~~~~~~~~~
+
+只需按照 Documentation/translations/zh_CN/admin-guide/reporting-issues.rst 中
+所說的報告你的問題,該文檔已經包含了要點。下面幾點概述了一下只在迴歸中重要的
+方面:
+
+ * 在檢查可加入討論的現有報告時,別忘了搜索 `Linux迴歸郵件列表
+   <https://lore.kernel.org/regressions/>`_ 和 `regzbot網頁界面
+   <https://linux-regtracking.leemhuis.info/regzbot/>`_ 。
+
+ * 在報告主題的開頭加上“[REGRESSION]”。
+
+ * 在你的報告中明確最後一個正常工作的內核版本和首個出問題的版本。如若可能,
+   用二分法嘗試找出導致迴歸的變更,更多細節見下。
+
+ * 記得把報告發到Linux迴歸郵件列表(regressions@lists.linux.dev)。
+
+   * 如果通過郵件報告迴歸,請抄送回歸列表。
+
+   * 如果你使用某些缺陷追蹤器報告迴歸,請通過郵件轉發已提交的報告到迴歸列表,
+     並抄送維護者以及出問題的相關子系統的郵件列表。
+
+   如果是穩定版或長期支持版系列(如v5.15.3…v5.15.5)的迴歸,請記得抄送
+   `Linux穩定版郵件列表 <https://lore.kernel.org/stable/>`_ (stable@vger.kernel.org)。
+
+  如果你成功地執行了二分,請抄送肇事提交的信息中所有簽了“Signed-off-by:”的人。
+
+在抄送你的報告到列表時,也請記得通知前述的Linux內核迴歸追蹤機器人。只需在郵件
+中包含如下片段::
+
+       #regzbot introduced: v5.13..v5.14-rc1
+
+Regzbot會就將你的郵件視爲在某個特定版本區間的迴歸報告。上例中即linux v5.13仍
+然正常,而Linux 5.14-rc1是首個您遇到問題的版本。如果你執行了二分以查找導致回
+歸的提交,請使用指定肇事提交的id代替::
+
+       #regzbot introduced: 1f2e3d4c5d
+
+添加這樣的“regzbot命令”對你是有好處的,它會確保報告不會被忽略。如果你省略了
+它,Linux內核的迴歸跟蹤者會把你的迴歸告訴regzbot,只要你發送了一個副本到迴歸
+郵件列表。但是迴歸跟蹤者只有一個人,有時不得不休息或甚至偶爾享受可以遠離電腦
+的時光(聽起來很瘋狂)。因此,依賴此人手動將回歸添加到 `已追蹤且尚未解決的
+Linux內核迴歸列表 <https://linux-regtracking.leemhuis.info/regzbot/>`_ 和
+regzbot發送的每週迴歸報告,可能會出現延遲。 這樣的延誤會導致Linus Torvalds
+在決定“繼續開發還是發佈新版本?”時忽略嚴重的迴歸。
+
+真的修復了所有的迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+幾乎所有都是,只要引起問題的變更(肇事提交)被可靠定位。也有些迴歸可以不用這
+樣,但通常是必須的。
+
+誰需要找出迴歸的根本原因?
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+受影響代碼區域的開發者應該自行嘗試定位問題所在。但僅靠他們的努力往往是不可
+能做到的,很多問題只發生在開發者的無法接觸的其他特定外部環境中——例如特定的
+硬件平臺、固件、Linux發行版、系統的配置或應用程序。這就是爲什麼最終往往是報
+告者定位肇事提交;有時用戶甚至需要再運行額外測試以查明確切的根本原因。開發
+者應該提供建議和可能的幫助,以使普通用戶更容易完成該流程。
+
+如何找到罪魁禍首?
+~~~~~~~~~~~~~~~~~~
+
+如 Documentation/translations/zh_CN/admin-guide/reporting-issues.rst (簡要)
+和 Documentation/translations/zh_CN/admin-guide/bug-bisect.rst (詳細)中所
+述,執行二分。聽起來工作量很大,但大部分情況下很快就能找到罪魁禍首。如果這很
+困難或可靠地重現問題很耗時,請考慮與其他受影響的用戶合作,一起縮小搜索範圍。
+
+當出現迴歸時我可以向誰尋求建議?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+發送郵件到迴歸郵件列表(regressions@lists.linux.dev)同時抄送Linux內核的迴歸
+跟蹤者(regressions@leemhuis.info);如果問題需要保密處理,可以省略列表。
+
+
+關於迴歸的更多細節
+------------------
+
+
+“無迴歸規則”的目標是什麼?
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+用戶應該放心升級內核版本,而不必擔心有程序可能崩潰。這符合內核開發者的利益,
+可以使更新有吸引力:他們不希望用戶停留在停止維護或超過一年半的穩定/長期Linux
+版本系列上。這也符合所有人的利益,因爲 `那些系列可能含有已知的缺陷、安全問題
+或其他後續版本已經修復的問題
+<http://www.kroah.com/log/blog/2018/08/24/what-stable-kernel-should-i-use/>`_ 。
+此外,內核開發者希望使用戶測試最新的預發行版或常規發行版變得簡單而有吸引力。
+這同樣符合所有人的利益,如果新版本出來後很快就有相關報告,會使追蹤和修復問題
+更容易。
+
+實際中“無迴歸”規則真的可行嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+這不是句玩笑話,請見Linux創建者和主要開發人員Linus Torvalds在郵件列表中的許
+多發言,其中一些在 Documentation/process/handling-regressions.rst 中被引用。
+
+此規則的例外情況極爲罕見;之前當開發者認爲某個特定的情況有必要援引例外時,
+基本都被證明錯了。
+
+誰來確保“無迴歸”被落實?
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+照看和支撐樹的子系統維護者應該關心這一點——例如,Linus Torvalds之於主線,
+Greg Kroah-Hartman等人之於各種穩定/長期系列。
+
+他們都得到了別人的幫助,以確保迴歸報告不會被遺漏。其中之一是Thorsten
+Leemhuis,他目前擔任Linux內核的“迴歸跟蹤者”;爲了做好這項工作,他使用了
+regzbot——Linux內核迴歸跟蹤機器人。所以這就是爲什麼要抄送或轉發你的報告到
+迴歸郵件列表來通知這些人,已經最好在你的郵件中包含“regzbot命令”來立即追蹤它。
+
+迴歸通常多久能修復?
+~~~~~~~~~~~~~~~~~~~~
+
+開發者應該儘快修復任何被報告的迴歸,以提供及時爲受影響的用戶提供解決方案,並
+防止更多用戶遇到問題;然而,開發人員需要花足夠的時間和注意力確保迴歸修復不會
+造成額外的損害。
+
+因此,答案取決於各種因素,如迴歸的影響、存在時長或出現於哪個Linux版本系列。
+但最終,大多數的迴歸應該在兩週內修復。
+
+當問題可以通過升級某些軟件解決時,是迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+基本都是。如果開發人員告訴您其他情況,請諮詢上述迴歸跟蹤者。
+
+當新內核變慢或能耗增加,是迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+是的,但有一些差別。在微型基準測試中變慢5%不太可能被視爲迴歸,除非它也會對
+廣泛基準測試的結果產生超過1%的影響。如果有疑問,請尋求建議。
+
+當更新Linux時外部內核模塊崩潰了,是迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+不,因爲“無迴歸”規則僅限於Linux內核提供給用戶空間的接口和服務。因此,它不包括
+構建或運行外部開發的內核模塊,因爲它們在內核空間中運行與掛進內核使用的內部接
+口偶爾會變化。
+
+如何處理安全修復引起的迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+在極爲罕見的情況下,安全問題無法在不引起迴歸的情況下修復;這些修復都被放棄了,
+因爲它們終究會引起問題。幸運的是這種兩難境地基本都可以避免,受影響區域的主要
+開發者以及Linus Torvalds本人通常都會努力在不引入迴歸的情況下解決安全問題。
+
+如果你仍然面臨此種情況,請查看郵件列表檔案是否有人盡力避免過迴歸。如果沒有,
+請報告它;如有疑問,請如上所述尋求建議。
+
+當修復迴歸時不可避免會引入另一個,如何處理?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+很遺憾這種事確實會出現,但幸運的是並不經常出現;如果發生了,受影響代碼區的資
+深開發者應當調查該問題以找到避免迴歸的解決方法,至少避免它們的影響。如果你遇
+到這樣的情況,如上所述:檢查之前的討論是否有人已經盡了最大努力,如有疑問請尋
+求建議。
+
+小提示:如果人們在每個開發週期中定期給出主線預發佈(即v5.15-rc1或-rc3)以供
+測試,則可以避免這種情況。爲了更好地解釋,可以設想一個在Linux v5.14和v5.15-rc1
+之間集成的更改,該更改導致了迴歸,但同時是應用於5.15-rc1的其他改進的強依賴。
+如果有人在5.15發佈之前就發現並報告了這個問題,那麼所有更改都可以直接撤銷,從
+而解決迴歸問題。而就在幾天或幾周後,此解決方案變成了不可能,因爲一些軟件可能
+已經開始依賴於後續更改之一:撤銷所有更改將導致上述用戶軟件出現迴歸,這是不可
+接受的。
+
+若我所依賴的功能在數月前被移除了,是迴歸嗎?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+是的,但如前節所述,通常很難修復此類迴歸。因此需要逐案處理。這也是定期測試主
+線預發佈對所有人有好處的另一個原因。
+
+如果我似乎是唯一受影響的人,是否仍適用“無迴歸”規則?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+適用,但僅限於實際使用:Linux開發人員希望能夠自由地取消那些只能在閣樓和博物
+館中找到的硬件的支持。
+
+請注意,有時爲了取得進展,不得不出現迴歸——後者也是防止Linux停滯不前所必需
+的。因此如果迴歸所影響的用戶很少,那麼爲了他們和其他人更大的利益,還是讓事情
+過去吧。尤其是存在某種規避迴歸的簡單方法,例如更新一些軟件或者使用專門爲此目
+的創建的內核參數。
+
+迴歸規則是否也適用於staging樹中的代碼?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+不,參見 `適用於所有staging代碼配置選項的幫助文本
+<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/staging/Kconfig>`_ ,
+其早已聲明::
+
+       請注意:這些驅動正在積極開發中,可能無法正常工作,並可能包含會在不久的
+       將來發生變化的用戶接口。
+
+雖然staging開發人員通常堅持“無迴歸”的原則,但有時爲了取得進展也會違背它。這就
+是爲什麼當staging樹的WiFi驅動被基本推倒重來時,有些用戶不得不處理迴歸(通常可
+以忽略)。
+
+爲什麼較新版本必須“使用相似配置編譯”?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+因爲Linux內核開發人員有時會集成已知的會導致迴歸的變更,但使它們成爲可選的,並
+在內核的默認配置下禁用它們。這一技巧允許進步,否則“無迴歸”規則將導致停滯。
+
+例如,試想一個新的可以阻止惡意軟件濫用某個內核的接口的安全特性,同時又需要滿足
+另一個很罕見的應用程序。上述的方法可使兩方都滿意:使用這些應用程序的人可以關閉
+新的安全功能,而其他不會遇到麻煩的人可以啓用它。
+
+如何創建與舊內核相似的配置?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+用一個已知良好的內核啓動機器,並用 ``make olddefconfig`` 配置新版的Linux。這
+會讓內核的構建腳本從正在運行的內核中摘錄配置文件(“.config”文件),作爲即將編
+譯的新版本的基礎配置;同時將所有新的配置選項設爲默認值,以禁用可能導致迴歸的
+新功能。
+
+如何報告在預編譯的普通內核中發現的迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+您需要確保新的內核是用與舊版相似的配置編譯(見上文),因爲那些構建它們的人可
+能啓用了一些已知的與新內核不兼容的特性。如有疑問,請向內核的提供者報告問題並
+尋求建議。
+
+
+用“regzbot”追蹤迴歸的更多信息
+-----------------------------
+
+什麼是迴歸追蹤?爲啥我需要關心它?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+像“無迴歸”這樣的規則需要有人來確保它們被遵守,否則會被有意/無意打破。歷史證
+明瞭這一點對於Linux內核開發也適用。這就是爲什麼Linux內核的迴歸跟蹤者Thorsten
+Leemhuis,,和另一些人盡力關注所有的迴歸直到他們解決。他們從未爲此獲得報酬,
+因此這項工作是在盡最大努力的基礎上完成的。
+
+爲什麼/如何使用機器人追蹤Linux內核迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+由於Linux內核開發過程的分佈式和鬆散結構,完全手動跟蹤迴歸已經被證明是相當困難
+的。因此Linux內核的迴歸跟蹤者開發了regzbot來促進這項工作,其長期目標是儘可能爲
+所有相關人員自動化迴歸跟蹤。
+
+Regzbot通過監視跟蹤的迴歸報告的回覆來工作。此外,它還查找用“Link:”標籤引用這
+些報告的補丁;對這些補丁的回覆也會被跟蹤。結合這些數據,可以很好地瞭解當前修
+復過程的狀態。
+
+如何查看regzbot當前追蹤的迴歸?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+參見 `regzbot在線 <https://linux-regtracking.leemhuis.info/regzbot/>`_ 。
+
+何種問題可以由regzbot追蹤?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+該機器人只爲了跟蹤迴歸,因此請不要讓regzbot涉及常規問題。但是對於Linux內核的
+迴歸跟蹤者來說,讓regzbot跟蹤嚴重問題也可以,如有關掛起、損壞數據或內部錯誤
+(Panic、Oops、BUG()、warning…)的報告。
+
+如何修改被追蹤迴歸的相關信息?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+在直接或間接回復報告郵件時使用“regzbot命令”即可。最簡單的方法是:在“已發送”文
+件夾或郵件列表存檔中找到報告,然後使用郵件客戶端的“全部回覆”功能對其進行回覆。
+在該郵件中的獨立段落中可使用以下命令之一(即使用空行將這些命令中的一個或多個與
+其餘郵件文本分隔開)。
+
+ * 更新迴歸引入起點,例如在執行二分之後::
+
+       #regzbot introduced: 1f2e3d4c5d
+
+ * 設置或更新標題::
+
+       #regzbot title: foo
+
+ * 監視討論或bugzilla.kernel.org上有關討論或修復的工單::
+
+       #regzbot monitor: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/
+       #regzbot monitor: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
+
+ * 標記一個有更多相關細節的地方,例如有關但主題不同的郵件列表帖子或缺陷追蹤器中的工單::
+
+       #regzbot link: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
+
+ * 標記迴歸已失效::
+
+       #regzbot invalid: wasn't a regression, problem has always existed
+
+Regzbot還支持其他一些主要由開發人員或迴歸追蹤人員使用的命令。命令的更多細節請
+參考 `入門指南 <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/getting_started.md>`_
+和 `參考手冊 <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/reference.md>`_ 。
+
+..
+   正文結束
+..
+   如本文件開頭所述,本文以GPL-2.0+或CC-BY-4.0許可發行。如您想僅在CC-BY-4.0許
+   可下重分發本文,請用“Linux內核開發者”作爲作者,並用如下鏈接作爲來源:
+   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/translations/zh_CN/admin-guide/reporting-regressions.rst
+..
+   注意:本RST文件內容只有在來自Linux內核源代碼時是使用CC-BY-4.0許可的,因爲經
+   過處理的版本(如經內核的構建系統)可能包含來自使用更嚴格許可證的文件的內容。
+
diff --git a/Documentation/translations/zh_TW/admin-guide/security-bugs.rst b/Documentation/translations/zh_TW/admin-guide/security-bugs.rst
index 15f8e9005071..c0e9fc247695 100644
--- a/Documentation/translations/zh_TW/admin-guide/security-bugs.rst
+++ b/Documentation/translations/zh_TW/admin-guide/security-bugs.rst
@@ -7,7 +7,7 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 安全缺陷
 =========
@@ -19,17 +19,17 @@ Linux內核開發人員非常重視安全性。因此我們想知道何時發現
 -----
 
 可以通過電子郵件<security@kernel.org>聯繫Linux內核安全團隊。這是一個安全人員
-的私有列表,他們將幫助驗證錯誤報告並開發和發布修復程序。如果您已經有了一個
+的私有列表,他們將幫助驗證錯誤報告並開發和發佈修復程序。如果您已經有了一個
 修復,請將其包含在您的報告中,這樣可以大大加快進程。安全團隊可能會從區域維護
-人員那裡獲得額外的幫助,以理解和修復安全漏洞。
+人員那裏獲得額外的幫助,以理解和修復安全漏洞。
 
 與任何缺陷一樣,提供的信息越多,診斷和修復就越容易。如果您不清楚哪些信息有用,
-請查看「Documentation/translations/zh_TW/admin-guide/reporting-issues.rst」中
+請查看“Documentation/translations/zh_CN/admin-guide/reporting-issues.rst”中
 概述的步驟。任何利用漏洞的攻擊代碼都非常有用,未經報告者同意不會對外發布,除
 非已經公開。
 
-請儘可能發送無附件的純文本電子郵件。如果所有的細節都藏在附件里,那麼就很難對
-一個複雜的問題進行上下文引用的討論。把它想像成一個
+請儘可能發送無附件的純文本電子郵件。如果所有的細節都藏在附件裏,那麼就很難對
+一個複雜的問題進行上下文引用的討論。把它想象成一個
 :doc:`常規的補丁提交 <../process/submitting-patches>` (即使你還沒有補丁):
 描述問題和影響,列出復現步驟,然後給出一個建議的解決方案,所有這些都是純文本的。
 
@@ -38,15 +38,15 @@ Linux內核開發人員非常重視安全性。因此我們想知道何時發現
 
 安全列表不是公開渠道。爲此,請參見下面的協作。
 
-一旦開發出了健壯的補丁,發布過程就開始了。對公開的缺陷的修復會立即發布。
+一旦開發出了健壯的補丁,發佈過程就開始了。對公開的缺陷的修復會立即發佈。
 
-儘管我們傾向於在未公開缺陷的修復可用時即發布補丁,但應報告者或受影響方的請求,
-這可能會被推遲到發布過程開始後的7日內,如果根據缺陷的嚴重性需要更多的時間,
-則可額外延長到14天。推遲發布修復的唯一有效原因是爲了適應QA的邏輯和需要發布
+儘管我們傾向於在未公開缺陷的修復可用時即發佈補丁,但應報告者或受影響方的請求,
+這可能會被推遲到發佈過程開始後的7日內,如果根據缺陷的嚴重性需要更多的時間,
+則可額外延長到14天。推遲發佈修復的唯一有效原因是爲了適應QA的邏輯和需要發佈
 協調的大規模部署。
 
 雖然可能與受信任的個人共享受限信息以開發修復,但未經報告者許可,此類信息不會
-與修復程序一起發布或發布在任何其他披露渠道上。這包括但不限於原始錯誤報告和
+與修復程序一起發佈或發佈在任何其他披露渠道上。這包括但不限於原始錯誤報告和
 後續討論(如有)、漏洞、CVE信息或報告者的身份。
 
 換句話說,我們唯一感興趣的是修復缺陷。提交給安全列表的所有其他資料以及對報告
@@ -57,10 +57,10 @@ Linux內核開發人員非常重視安全性。因此我們想知道何時發現
 
 對敏感缺陷(例如那些可能導致權限提升的缺陷)的修復可能需要與私有郵件列表
 <linux-distros@vs.openwall.org>進行協調,以便分發供應商做好準備,在公開披露
-上游補丁時發布一個已修復的內核。發行版將需要一些時間來測試建議的補丁,通常
-會要求至少幾天的限制,而供應商更新發布更傾向於周二至周四。若合適,安全團隊
+上游補丁時發佈一個已修復的內核。發行版將需要一些時間來測試建議的補丁,通常
+會要求至少幾天的限制,而供應商更新發布更傾向於週二至週四。若合適,安全團隊
 可以協助這種協調,或者報告者可以從一開始就包括linux發行版。在這種情況下,請
-記住在電子郵件主題行前面加上「[vs]」,如linux發行版wiki中所述:
+記住在電子郵件主題行前面加上“[vs]”,如linux發行版wiki中所述:
 <http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists>。
 
 CVE分配
diff --git a/Documentation/translations/zh_TW/admin-guide/sysrq.rst b/Documentation/translations/zh_TW/admin-guide/sysrq.rst
new file mode 100644
index 000000000000..446277674b64
--- /dev/null
+++ b/Documentation/translations/zh_TW/admin-guide/sysrq.rst
@@ -0,0 +1,283 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_TW.rst
+
+:Original: Documentation/admin-guide/sysrq.rst
+
+:翻譯:
+
+ 黃軍華 Junhua Huang <huang.junhua@zte.com.cn>
+
+:校譯:
+
+ 司延騰 Yanteng Si <siyanteng@loongson.cn>
+
+.. _tw_admin-guide_sysrq:
+
+Linux 魔法系統請求鍵駭客
+========================
+
+針對 sysrq.c 的文檔說明
+
+什麼是魔法 SysRq 鍵?
+~~~~~~~~~~~~~~~~~~~~~
+
+它是一個你可以輸入的具有魔法般的組合鍵。
+無論內核在做什麼,內核都會響應 SysRq 鍵的輸入,除非內核完全卡死。
+
+如何使能魔法 SysRq 鍵?
+~~~~~~~~~~~~~~~~~~~~~~~
+
+在配置內核時,我們需要設置 'Magic SysRq key (CONFIG_MAGIC_SYSRQ)' 爲 'Y'。
+當運行一個編譯進 sysrq 功能的內核時,/proc/sys/kernel/sysrq 控制着被
+SysRq 鍵調用的功能許可。這個文件的默認值由 CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE
+配置符號設定,文件本身默認設置爲 1。以下是 /proc/sys/kernel/sysrq 中可能的
+值列表:
+
+   -  0 - 完全不使能 SysRq 鍵
+   -  1 - 使能 SysRq 鍵的全部功能
+   - >1 - 對於允許的 SysRq 鍵功能的比特掩碼(參見下面更詳細的功能描述)::
+
+          2 =   0x2 - 使能對控制檯日誌記錄級別的控制
+          4 =   0x4 - 使能對鍵盤的控制 (SAK, unraw)
+          8 =   0x8 - 使能對進程的調試導出等
+         16 =  0x10 - 使能同步命令
+         32 =  0x20 - 使能重新掛載只讀
+         64 =  0x40 - 使能對進程的信號操作 (term, kill, oom-kill)
+        128 =  0x80 - 允許重啓、斷電
+        256 = 0x100 - 允許讓所有實時任務變普通任務
+
+你可以通過如下命令把值設置到這個文件中::
+
+    echo "number" >/proc/sys/kernel/sysrq
+
+這裏被寫入的 number 可以是 10 進制數,或者是帶着 0x 前綴的 16 進制數。
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE 必須是以 16 進制數寫入。
+
+注意,``/proc/sys/kernel/sysrq`` 的值隻影響通過鍵盤觸發 SySRq 的調用,對於
+通過 ``/proc/sysrq-trigger`` 的任何操作調用都是允許的
+(通過具有系統權限的用戶)。
+
+如何使用魔法 SysRq 鍵?
+~~~~~~~~~~~~~~~~~~~~~~~
+
+在 x86 架構上
+	你可以按下鍵盤組合鍵 :kbd:`ALT-SysRq-<command key>`。
+
+	.. note::
+	   一些鍵盤可能沒有標識 'SySRq' 鍵。'SySRq' 鍵也被當做 'Print Screen'鍵。
+	   同時有些鍵盤無法處理同時按下這麼多鍵,因此你可以先按下鍵盤 :kbd:`Alt` 鍵,
+	   然後按下鍵盤 :kbd:`SysRq` 鍵,再釋放鍵盤 :kbd:`SysRq` 鍵,之後按下鍵盤上命令鍵
+	   :kbd:`<command key>`,最後釋放所有鍵。
+
+在 SPARC 架構上
+	你可以按下鍵盤組合鍵 :kbd:`ALT-STOP-<command key>` 。
+
+在串行控制檯(只針對 PC 類型的標準串口)
+        你可以發一個 ``BREAK`` ,然後在 5 秒內發送一個命令鍵,
+	發送 ``BREAK`` 兩次將被翻譯爲一個正常的 BREAK 操作。
+
+在 PowerPC 架構上
+	按下鍵盤組合鍵 :kbd:`ALT - Print Screen` (或者 :kbd:`F13`) - :kbd:`<命令鍵>` 。
+        :kbd:`Print Screen` (或者 :kbd:`F13`) - :kbd:`<命令鍵>` 或許也能實現。
+
+在其他架構上
+	如果你知道其他架構的組合鍵,請告訴我,我可以把它們添加到這部分。
+
+在所有架構上
+	寫一個字符到 /proc/sysrq-trigger 文件,例如::
+
+		echo t > /proc/sysrq-trigger
+
+這個命令鍵 :kbd:`<command key>` 是區分大小寫的。
+
+什麼是命令鍵?
+~~~~~~~~~~~~~~
+
+=========== ================================================================
+命令鍵	    功能
+=========== ================================================================
+``b``	    將立即重啓系統,不會同步或者卸載磁盤。
+
+``c``	    將執行系統 crash,如果配置了系統 crashdump,將執行 crashdump。
+
+``d``	    顯示所有持有的鎖。
+
+``e``	    發送 SIGTERM 信號給所有進程,除了 init 進程。
+
+``f``	    將調用 oom killer 殺掉一個過度佔用內存的進程,如果什麼任務都沒殺,
+            也不會 panic。
+
+``g``	    kgdb 使用(內核調試器)。
+
+``h``	    將會顯示幫助。(實際上除了這裏列舉的鍵,其他的都將顯示幫助,
+	    但是 ``h`` 容易記住):-)
+
+``i``	    發送 SIGKILL 給所有進程,除了 init 進程。
+
+``j``	    強制性的 “解凍它” - 用於被 FIFREEZE ioctl 操作凍住的文件系統。
+
+``k``	    安全訪問祕鑰(SAK)殺掉在當前虛擬控制檯的所有程序,注意:參考
+            下面 SAK 節重要論述。
+
+``l``	    顯示所有活動 cpu 的棧回溯。
+
+``m``	    將導出當前內存信息到你的控制檯。
+
+``n``	    用於使所有實時任務變成普通任務。
+
+``o``	    將關閉系統(如果配置和支持的話)。
+
+``p``	    將導出當前寄存器和標誌位到控制檯。
+
+``q``	    將導出每個 cpu 上所有已裝備的高精度定時器(不是完整的
+            time_list 文件顯示的 timers)和所有時鐘事件設備的詳細信息。
+
+``r``	    關閉鍵盤的原始模式,設置爲轉換模式。
+
+``s``	    將嘗試同步所有的已掛載文件系統。
+
+``t``	    將導出當前所有任務列表和它們的信息到控制檯。
+
+``u``	    將嘗試重新掛載已掛載文件系統爲只讀。
+
+``v``	    強制恢復幀緩存控制檯。
+``v``	    觸發 ETM 緩存導出 [ARM 架構特有]
+
+``w``	    導出處於不可中斷狀態(阻塞)的任務。
+
+``x``	    在 ppc/powerpc 架構上用於 xmon 接口。
+            在 sparc64 架構上用於顯示全局的 PMU(性能監控單元)寄存器。
+            在 MIPS 架構上導出所有的 tlb 條目。
+
+``y``	    顯示全局 cpu 寄存器 [SPARC-64 架構特有]
+
+``z``	    導出 ftrace 緩存信息
+
+``0``-``9`` 設置控制檯日誌級別,該級別控制什麼樣的內核信息將被打印到你的
+	    控制檯。(比如 ``0`` ,將使得只有緊急信息,像 PANICs or OOPSes
+	    才能到你的控制檯。)
+=========== ================================================================
+
+好了,我能用他們做什麼呢?
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+嗯,當你的 X 服務端或者 svgalib 程序崩潰,unraw(r) 非原始模式命令鍵是非常
+方便的。
+
+sak(k)(安全訪問祕鑰)在你嘗試登陸的同時,又想確保當前控制檯沒有可以獲取你的
+密碼的特洛伊木馬程序運行時是有用的。它會殺掉給定控制檯的所有程序,這樣你
+就可以確認當前的登陸提示程序是實際來自 init 進程的程序,而不是某些特洛伊
+木馬程序。
+
+.. important::
+
+   在其實際的形式中,在兼容 C2 安全標準的系統上,它不是一個真正的 SAK,
+   它也不應該誤認爲此。
+
+似乎其他人發現其可以作爲(系統終端聯機鍵)當你想退出一個程序,
+同時不會讓你切換控制檯的方法。(比如,X 服務端或者 svgalib 程序)
+
+``reboot(b)`` 是個好方法,當你不能關閉機器時,它等同於按下"復位"按鈕。
+
+``crash(c)`` 可以用於手動觸發一個 crashdump,當系統卡住時。
+注意當 crashdump 機制不可用時,這個只是觸發一個內核 crash。
+
+``sync(s)`` 在拔掉可移動介質之前,或者在使用不提供優雅關機的
+救援 shell 之後很方便 -- 它將確保你的數據被安全地寫入磁盤。注意,在你看到
+屏幕上出現 "OK" 和 "Done" 之前,同步還沒有發生。
+
+``umount(u)`` 可以用來標記文件系統正常卸載,從正在運行的系統角度來看,它們將
+被重新掛載爲只讀。這個重新掛載動作直到你看到 "OK" 和 "Done" 信息出現在屏幕上
+纔算完成。
+
+日誌級別 ``0`` - ``9`` 用於當你的控制檯被大量的內核信息衝擊,你不想看見的時候。
+選擇 ``0`` 將禁止除了最緊急的內核信息外的所有的內核信息輸出到控制檯。(但是如果
+syslogd/klogd 進程是運行的,它們仍將被記錄。)
+
+``term(e)`` 和 ``kill(i)`` 用於當你有些有點失控的進程,你無法通過其他方式殺掉
+它們的時候,特別是它正在創建其他進程。
+
+"just thaw ``it(j)`` " 用於當你的系統由於一個 FIFREEZE ioctl 調用而產生的文件
+系統凍結,而導致的不響應時。
+
+有的時候 SysRq 鍵在使用它之後,看起來像是“卡住”了,我能做些什麼?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+這也會發生在我這,我發現輕敲鍵盤兩側的 shift、alt 和 control 鍵,然後再次敲擊
+一個無效的 SysRq 鍵序列可以解決問題。(比如,像鍵盤組合鍵 :kbd:`alt-sysrq-z` )
+切換到另一個虛擬控制檯(鍵盤操作 :kbd:`ALT+Fn` ),然後再切回來應該也有幫助。
+
+我敲擊了 SysRq 鍵,但像是什麼都沒發生,發生了什麼錯誤?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+有一些鍵盤對於 SysRq 鍵設置了不同的鍵值,而不是提前定義的 99
+(查看在 ``include/uapi/linux/input-event-codes.h`` 文件中 ``KEY_SYSRQ`` 的定義)
+或者就根本沒有 SysRq 鍵。在這些場景下,執行 ``showkey -s`` 命令來找到一個合適
+的掃描碼序列,然後使用 ``setkeycodes <sequence> 99`` 命令映射這個序列值到通用
+的 SysRq 鍵編碼上(比如 ``setkeycodes e05b 99`` )。最好將這個命令放在啓動腳本
+中。
+哦,順便說一句,你十秒鐘不輸入任何東西就將退出 “showkey”。
+
+我想添加一個 SysRq 鍵事件到一個模塊中,如何去做呢?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+爲了註冊一個基礎函數到這個表中,首先你必須包含 ``include/linux/sysrq.h`` 頭
+文件,這個頭文件定義了你所需要的所有東西。然後你必須創建一個 ``sysrq_key_op``
+結構體,然後初始化它,使用如下內容,A) 你將使用的這個鍵的處理函數, B) 一個
+help_msg 字符串,在 SysRq 鍵打印幫助信息時將打印出來,C) 一個 action_msg 字
+符串,就在你的處理函數調用前打印出來。你的處理函數必須符合在 'sysrq.h' 文件中
+的函數原型。
+
+在 ``sysrq_key_op`` 結構體被創建後,你可以調用內核函數
+``register_sysrq_key(int key, const struct sysrq_key_op *op_p);``,
+該函數在表中的 'key' 對應位置內容是空的情況下,將通過 ``op_p`` 指針註冊這個操作
+函數到表中 'key' 對應位置上。在模塊卸載的時候,你必須調用
+``unregister_sysrq_key(int key, const struct sysrq_key_op *op_p)`` 函數,該函數
+只有在當前該鍵對應的處理函數被註冊到了 'key' 對應位置時,纔會移除 'op_p' 指針
+對應的鍵值操作函數。這是爲了防止在你註冊之後,該位置被改寫的情況。
+
+魔法 SysRq 鍵系統的工作原理是將鍵對應操作函數註冊到鍵的操作查找表,
+該表定義在 'drivers/tty/sysrq.c' 文件中。
+該鍵表有許多在編譯時候就註冊進去的操作函數,但是是可變的。
+並且有兩個函數作爲操作該表的接口被導出::
+
+	register_sysrq_key 和 unregister_sysrq_key.
+
+當然,永遠不要在表中留下無效指針,即,當你的模塊存在調用 register_sysrq_key()
+函數,它一定要調用 unregister_sysrq_key() 來清除它使用過的 SysRq 鍵表條目。
+表中的空指針是安全的。:)
+
+如果對於某種原因,在 handle_sysrq 調用的處理函數中,你認爲有必要調用
+handle_sysrq 函數時,你必須意識到當前你處於一個鎖中(你同時也處於一箇中斷處理
+函數中,這意味着不能睡眠)。所以這時你必須使用 ``__handle_sysrq_nolock`` 替代。
+
+當我敲擊一個 SysRq 組合鍵時,只有標題打印出現在控制檯?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SysRq 鍵的輸出和所有其他控制檯輸出一樣,受制於控制檯日誌級別控制。
+這意味着,如果內核以發行版內核中常見的 "quiet" 方式啓動,則輸出可能不會出現在實際
+的控制檯上,即使它會出現在 dmesg 緩存中,也可以通過 dmesg 命令和 ``/proc/kmsg``
+文件的消費訪問到。作爲一個特例,來自 sysrq 命令的標題行將被傳遞給所有控制檯
+使用者,就好像當前日誌級別是最大的一樣。如果只發出標題頭,則幾乎可以肯定內核日誌
+級別太低。如果你需要控制檯上的輸出,那麼你將需要臨時提高控制檯日誌級別,通過使用
+鍵盤組合鍵 :kbd:`alt-sysrq-8` 或者::
+
+    echo 8 > /proc/sysrq-trigger
+
+在觸發了你感興趣的 SysRq 鍵命令後,記得恢復日誌級別到正常情況。
+
+我有很多問題時,可以請教誰?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+請教在內核郵件列表上的人,郵箱:
+	linux-kernel@vger.kernel.org
+
+致謝
+~~~~
+
+- Mydraal <vulpyne@vulpyne.net> 撰寫了該文件
+- Adam Sulmicki <adam@cfar.umd.edu> 進行了更新
+- Jeremy M. Dolan <jmd@turbogeek.org> 在 2001/01/28 10:15:59 進行了更新
+- Crutcher Dunnavant <crutcher+kernel@datastacks.com> 添加鍵註冊部分
+
diff --git a/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst b/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst
index d7b3c4276417..47629f6b05de 100644
--- a/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst
+++ b/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst
@@ -7,29 +7,29 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
-受汙染的內核
+受污染的內核
 -------------
 
-當發生一些在稍後調查問題時可能相關的事件時,內核會將自己標記爲「受汙染
-(tainted)」的。不用太過擔心,大多數情況下運行受汙染的內核沒有問題;這些信息
-主要在有人想調查某個問題時才有意義的,因爲問題的真正原因可能是導致內核受汙染
-的事件。這就是爲什麼來自受汙染內核的缺陷報告常常被開發人員忽略,因此請嘗試用
-未受汙染的內核重現問題。
+當發生一些在稍後調查問題時可能相關的事件時,內核會將自己標記爲“受污染
+(tainted)”的。不用太過擔心,大多數情況下運行受污染的內核沒有問題;這些信息
+主要在有人想調查某個問題時纔有意義的,因爲問題的真正原因可能是導致內核受污染
+的事件。這就是爲什麼來自受污染內核的缺陷報告常常被開發人員忽略,因此請嘗試用
+未受污染的內核重現問題。
 
-請注意,即使在您消除導致汙染的原因(亦即卸載專有內核模塊)之後,內核仍將保持
-汙染狀態,以表示內核仍然不可信。這也是爲什麼內核在注意到內部問題(「kernel
-bug」)、可恢復錯誤(「kernel oops」)或不可恢復錯誤(「kernel panic」)時會列印
-受汙染狀態,並將有關此的調試信息寫入日誌 ``dmesg`` 輸出。也可以通過
-``/proc/`` 中的文件在運行時檢查受汙染的狀態。
+請注意,即使在您消除導致污染的原因(亦即卸載專有內核模塊)之後,內核仍將保持
+污染狀態,以表示內核仍然不可信。這也是爲什麼內核在注意到內部問題(“kernel
+bug”)、可恢復錯誤(“kernel oops”)或不可恢復錯誤(“kernel panic”)時會打印
+受污染狀態,並將有關此的調試信息寫入日誌 ``dmesg`` 輸出。也可以通過
+``/proc/`` 中的文件在運行時檢查受污染的狀態。
 
 
-BUG、Oops或Panics消息中的汙染標誌
+BUG、Oops或Panics消息中的污染標誌
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-在頂部以「CPU:」開頭的一行中可以找到受汙染的狀態;內核是否受到汙染和原因會顯示
-在進程ID(「PID:」)和觸發事件命令的縮寫名稱(「Comm:」)之後::
+在頂部以“CPU:”開頭的一行中可以找到受污染的狀態;內核是否受到污染和原因會顯示
+在進程ID(“PID:”)和觸發事件命令的縮寫名稱(“Comm:”)之後::
 
 	BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
 	Oops: 0002 [#1] SMP PTI
@@ -38,27 +38,27 @@ BUG、Oops或Panics消息中的汙染標誌
 	RIP: 0010:my_oops_init+0x13/0x1000 [kpanic]
 	[...]
 
-如果內核在事件發生時沒有被汙染,您將在那裡看到「Not-tainted:」;如果被汙染,那
-麼它將是「Tainted:」以及字母或空格。在上面的例子中,它看起來是這樣的::
+如果內核在事件發生時沒有被污染,您將在那裏看到“Not-tainted:”;如果被污染,那
+麼它將是“Tainted:”以及字母或空格。在上面的例子中,它看起來是這樣的::
 
 	Tainted: P        W  O
 
 下表解釋了這些字符的含義。在本例中,由於加載了專有模塊( ``P`` ),出現了
 警告( ``W`` ),並且加載了外部構建的模塊( ``O`` ),所以內核早些時候受到
-了汙染。要解碼其他字符,請使用下表。
+了污染。要解碼其他字符,請使用下表。
 
 
-解碼運行時的汙染狀態
+解碼運行時的污染狀態
 ~~~~~~~~~~~~~~~~~~~~~
 
-在運行時,您可以通過讀取 ``cat /proc/sys/kernel/tainted`` 來查詢受汙染狀態。
-如果返回 ``0`` ,則內核沒有受到汙染;任何其他數字都表示受到汙染的原因。解碼
+在運行時,您可以通過讀取 ``cat /proc/sys/kernel/tainted`` 來查詢受污染狀態。
+如果返回 ``0`` ,則內核沒有受到污染;任何其他數字都表示受到污染的原因。解碼
 這個數字的最簡單方法是使用腳本  ``tools/debugging/kernel-chktaint`` ,您的
 發行版可能會將其作爲名爲 ``linux-tools`` 或 ``kernel-tools`` 的包的一部分提
 供;如果沒有,您可以從
 `git.kernel.org <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/tools/debugging/kernel-chktaint>`_
 網站下載此腳本並用 ``sh kernel-chktaint`` 執行,它會在上面引用的日誌中有類似
-語句的機器上列印這樣的內容::
+語句的機器上打印這樣的內容::
 
 	Kernel is Tainted for following reasons:
 	 * Proprietary module was loaded (#0)
@@ -69,19 +69,19 @@ BUG、Oops或Panics消息中的汙染標誌
 	 a more details explanation of the various taint flags.
 	Raw taint value as int/string: 4609/'P        W  O     '
 
-你也可以試著自己解碼這個數字。如果內核被汙染的原因只有一個,那麼這很簡單,
+你也可以試着自己解碼這個數字。如果內核被污染的原因只有一個,那麼這很簡單,
 在本例中您可以通過下表找到數字。如果你需要解碼有多個原因的數字,因爲它是一
-個位域(bitfield),其中每個位表示一個特定類型的汙染的存在或不存在,最好讓
+個位域(bitfield),其中每個位表示一個特定類型的污染的存在或不存在,最好讓
 前面提到的腳本來處理。但是如果您需要快速看一下,可以使用這個shell命令來檢查
 設置了哪些位::
 
 	$ for i in $(seq 18); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done
 
-汙染狀態代碼表
+污染狀態代碼表
 ~~~~~~~~~~~~~~~
 
 ===  =====  ======  ========================================================
- 位  日誌     數字  內核被汙染的原因
+ 位  日誌     數字  內核被污染的原因
 ===  =====  ======  ========================================================
   0   G/P        1  已加載專用模塊
   1   _/F        2  模塊被強制加載
@@ -89,23 +89,23 @@ BUG、Oops或Panics消息中的汙染標誌
   3   _/R        8  模塊被強制卸載
   4   _/M       16  處理器報告了機器檢測異常(MCE)
   5   _/B       32  引用了錯誤的頁或某些意外的頁標誌
-  6   _/U       64  用戶空間應用程式請求的汙染
+  6   _/U       64  用戶空間應用程序請求的污染
   7   _/D      128  內核最近死機了,即曾出現OOPS或BUG
   8   _/A      256  ACPI表被用戶覆蓋
   9   _/W      512  內核發出警告
  10   _/C     1024  已加載staging驅動程序
- 11   _/I     2048  已應用平台固件缺陷的解決方案
- 12   _/O     4096  已加載外部構建(「樹外」)模塊
+ 11   _/I     2048  已應用平臺固件缺陷的解決方案
+ 12   _/O     4096  已加載外部構建(“樹外”)模塊
  13   _/E     8192  已加載未簽名的模塊
  14   _/L    16384  發生軟鎖定
  15   _/K    32768  內核已實時打補丁
- 16   _/X    65536  備用汙染,爲發行版定義並使用
+ 16   _/X    65536  備用污染,爲發行版定義並使用
  17   _/T   131072  內核是用結構隨機化插件構建的
 ===  =====  ======  ========================================================
 
-註:字符 ``_`` 表示空白,以便於閱讀表。
+注:字符 ``_`` 表示空白,以便於閱讀表。
 
-汙染的更詳細解釋
+污染的更詳細解釋
 ~~~~~~~~~~~~~~~~~
 
  0)  ``G`` 加載的所有模塊都有GPL或兼容許可證, ``P`` 加載了任何專有模塊。
@@ -115,14 +115,14 @@ BUG、Oops或Panics消息中的汙染標誌
 
  1)  ``F`` 任何模塊被 ``insmod -f`` 強制加載, ``' '`` 所有模塊正常加載。
 
- 2)  ``S`` 內核運行在不合規範的處理器或系統上:硬體已運行在不受支持的配置中,
-     因此無法保證正確執行。內核將被汙染,例如:
+ 2)  ``S`` 內核運行在不合規範的處理器或系統上:硬件已運行在不受支持的配置中,
+     因此無法保證正確執行。內核將被污染,例如:
 
      - 在x86上:PAE是通過intel CPU(如Pentium M)上的forcepae強制執行的,這些
        CPU不報告PAE,但可能有功能實現,SMP內核在非官方支持的SMP Athlon CPU上
        運行,MSR被暴露到用戶空間中。
      - 在arm上:在某些CPU(如Keystone 2)上運行的內核,沒有啓用某些內核特性。
-     - 在arm64上:CPU之間存在不匹配的硬體特性,引導加載程序以不同的模式引導CPU。
+     - 在arm64上:CPU之間存在不匹配的硬件特性,引導加載程序以不同的模式引導CPU。
      - 某些驅動程序正在被用在不受支持的體系結構上(例如x86_64以外的其他系統
        上的scsi/snic,非x86/x86_64/itanium上的scsi/ips,已經損壞了arm64上
        irqchip/irq-gic的固件設置…)。
@@ -131,22 +131,22 @@ BUG、Oops或Panics消息中的汙染標誌
 
  4)  ``M`` 任何處理器報告了機器檢測異常, ``' '`` 未發生機器檢測異常。
 
- 5)  ``B`` 頁面釋放函數發現錯誤的頁面引用或某些意外的頁面標誌。這表示硬體問題
-     或內核錯誤;日誌中應該有其他信息指示發生此汙染的原因。
+ 5)  ``B`` 頁面釋放函數發現錯誤的頁面引用或某些意外的頁面標誌。這表示硬件問題
+     或內核錯誤;日誌中應該有其他信息指示發生此污染的原因。
 
- 6)  ``U`` 用戶或用戶應用程式特意請求設置受汙染標誌,否則應爲 ``' '`` 。
+ 6)  ``U`` 用戶或用戶應用程序特意請求設置受污染標誌,否則應爲 ``' '`` 。
 
  7)  ``D`` 內核最近死機了,即出現了OOPS或BUG。
 
  8)  ``A`` ACPI表被重寫。
 
- 9)  ``W`` 內核之前已發出過警告(儘管有些警告可能會設置更具體的汙染標誌)。
+ 9)  ``W`` 內核之前已發出過警告(儘管有些警告可能會設置更具體的污染標誌)。
 
  10) ``C`` 已加載staging驅動程序。
 
- 11) ``I`` 內核正在處理平台固件(BIOS或類似軟體)中的嚴重錯誤。
+ 11) ``I`` 內核正在處理平臺固件(BIOS或類似軟件)中的嚴重錯誤。
 
- 12) ``O`` 已加載外部構建(「樹外」)模塊。
+ 12) ``O`` 已加載外部構建(“樹外”)模塊。
 
  13) ``E`` 在支持模塊簽名的內核中加載了未簽名的模塊。
 
@@ -154,8 +154,8 @@ BUG、Oops或Panics消息中的汙染標誌
 
  15) ``K`` 內核已經實時打了補丁。
 
- 16) ``X`` 備用汙染,由Linux發行版定義和使用。
+ 16) ``X`` 備用污染,由Linux發行版定義和使用。
 
  17) ``T`` 內核構建時使用了randstruct插件,它可以有意生成非常不尋常的內核結構
-     布局(甚至是性能病態的布局),這在調試時非常有用。於構建時設置。
+     佈局(甚至是性能病態的佈局),這在調試時非常有用。於構建時設置。
 
diff --git a/Documentation/translations/zh_TW/admin-guide/unicode.rst b/Documentation/translations/zh_TW/admin-guide/unicode.rst
index 720875be5ef8..a2b48b5d0a64 100644
--- a/Documentation/translations/zh_TW/admin-guide/unicode.rst
+++ b/Documentation/translations/zh_TW/admin-guide/unicode.rst
@@ -7,7 +7,7 @@
 :譯者:
 
  吳想成 Wu XiangCheng <bobwxc@email.cn>
- 胡皓文 Hu Haowen <src.res@email.cn>
+ 胡皓文 Hu Haowen <src.res.211@gmail.com>
 
 Unicode(統一碼)支持
 ======================
@@ -37,15 +37,15 @@ IBMPC_MAP       IBM code page 437               ESC ( U
 USER_MAP        User defined                    ESC ( K
 =============== =============================== ================
 
-特別是 ESC ( U 不再是「直通字體」,因爲字體可能與IBM字符集完全不同。
+特別是 ESC ( U 不再是“直通字體”,因爲字體可能與IBM字符集完全不同。
 例如,即使加載了一個Latin-1字體,也允許使用塊圖形(block graphics)。
 
 請注意,儘管這些代碼與ISO 2022類似,但這些代碼及其用途都與ISO 2022不匹配;
 Linux有兩個八位代碼(G0和G1),而ISO 2022有四個七位代碼(G0-G3)。
 
-根據Unicode標準/ISO 10646,U+F000到U+F8FF被保留用於作業系統範圍內的分配
-(Unicode標準將其稱爲「團體區域(Corporate Zone)」,因爲這對於Linux是不準確
-的,所以我們稱之爲「Linux區域」)。選擇U+F000作爲起點,因爲它允許直接映射
+根據Unicode標準/ISO 10646,U+F000到U+F8FF被保留用於操作系統範圍內的分配
+(Unicode標準將其稱爲“團體區域(Corporate Zone)”,因爲這對於Linux是不準確
+的,所以我們稱之爲“Linux區域”)。選擇U+F000作爲起點,因爲它允許直接映射
 區域以2的大倍數開始(以防需要1024或2048個字符的字體)。這就留下U+E000到
 U+EFFF作爲最終用戶區。
 
@@ -87,7 +87,7 @@ U+F813 KEYBOARD SYMBOL SOLID APPLE
 克林貢(Klingon)語支持
 ------------------------
 
-1996年,Linux是世界上第一個添加對人工語言克林貢支持的作業系統,克林貢是由
+1996年,Linux是世界上第一個添加對人工語言克林貢支持的操作系統,克林貢是由
 Marc Okrand爲《星際迷航》電視連續劇創造的。這種編碼後來被徵募Unicode註冊表
 (ConScript Unicode Registry,CSUR)採用,並建議(但最終被拒絕)納入Unicode
 平面一。不過,它仍然是Linux區域中的Linux/CSUR私有分配。
-- 
2.34.1


^ permalink raw reply related	[relevance 4%]

* [merged mm-stable] mm-damon-rename-config_damon_dbgfs-to-damon_dbgfs_deprecated.patch removed from -mm tree
@ 2024-02-22  0:02  4% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2024-02-22  0:02 UTC (permalink / raw)
  To: mm-commits, siyanteng, shuah, corbet, alexs, 2023002089, sj, akpm


The quilt patch titled
     Subject: mm/damon: rename CONFIG_DAMON_DBGFS to DAMON_DBGFS_DEPRECATED
has been removed from the -mm tree.  Its filename was
     mm-damon-rename-config_damon_dbgfs-to-damon_dbgfs_deprecated.patch

This patch was dropped because it was merged into the mm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: mm/damon: rename CONFIG_DAMON_DBGFS to DAMON_DBGFS_DEPRECATED
Date: Mon, 29 Jan 2024 17:35:41 -0800

DAMON debugfs interface is deprecated.  The fact has documented by commit
5445fcbc4cda ("Docs/admin-guide/mm/damon/usage: add DAMON debugfs
interface deprecation notice").  Commit 620932cd2852 ("mm/damon/dbgfs:
print DAMON debugfs interface deprecation message") further started
printing a warning message when users still use it.  Many people don't
read documentation or kernel log, though.

Make the deprecation harder to be ignored using the approach of commit
eb07c4f39c3e ("mm/slab: rename CONFIG_SLAB to CONFIG_SLAB_DEPRECATED"). 
'make oldconfig' with 'CONFIG_DAMON_DBGFS=y' will get a new prompt with
the explicit deprecation notice on the name.  'make olddefconfig' with
'CONFIG_DAMON_DBGFS=y' will result in not building DAMON debugfs
interface.  If there is a real user of DAMON debugfs interface, they will
complain the change to the builder.

Link: https://lkml.kernel.org/r/20240130013549.89538-3-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Alex Shi <alexs@kernel.org>
Cc: Hu Haowen <2023002089@link.tyut.edu.cn>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Yanteng Si <siyanteng@loongson.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 mm/damon/Kconfig |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

--- a/mm/damon/Kconfig~mm-damon-rename-config_damon_dbgfs-to-damon_dbgfs_deprecated
+++ a/mm/damon/Kconfig
@@ -71,7 +71,7 @@ config DAMON_SYSFS_KUNIT_TEST
 
 	  If unsure, say N.
 
-config DAMON_DBGFS
+config DAMON_DBGFS_DEPRECATED
 	bool "DAMON debugfs interface (DEPRECATED!)"
 	depends on DAMON_VADDR && DAMON_PADDR && DEBUG_FS
 	help
@@ -84,6 +84,11 @@ config DAMON_DBGFS
 	  (DAMON_SYSFS).  If you depend on this and cannot move, please report
 	  your usecase to damon@lists.linux.dev and linux-mm@kvack.org.
 
+config DAMON_DBGFS
+	bool
+	default y
+	depends on DAMON_DBGFS_DEPRECATED
+
 config DAMON_DBGFS_KUNIT_TEST
 	bool "Test for damon debugfs interface" if !KUNIT_ALL_TESTS
 	depends on DAMON_DBGFS && KUNIT=y
_

Patches currently in -mm which might be from sj@kernel.org are

docs-mm-damon-maintainer-profile-fix-reference-links-for-mm-stable-tree.patch
docs-mm-damon-move-the-list-of-damos-actions-to-design-doc.patch
docs-mm-damon-move-damon-operation-sets-list-from-the-usage-to-the-design-document.patch
docs-mm-damon-move-damon-operation-sets-list-from-the-usage-to-the-design-document-fix.patch
docs-mm-damon-move-monitoring-target-regions-setup-detail-from-the-usage-to-the-design-document.patch
docs-admin-guide-mm-damon-usage-fix-wrong-quotas-diabling-condition.patch
mm-damon-core-set-damos_quota-esz-as-public-field-and-document.patch
mm-damon-sysfs-schemes-implement-quota-effective_bytes-file.patch
mm-damon-sysfs-implement-a-kdamond-command-for-updating-schemes-effective-quotas.patch
docs-abi-damon-document-effective_bytes-sysfs-file.patch
docs-admin-guide-mm-damon-usage-document-effective_bytes-file.patch
mm-damon-move-comments-and-fields-for-damos-quota-prioritization-to-the-end.patch
mm-damon-core-split-out-quota-goal-related-fields-to-a-struct.patch
mm-damon-core-add-multiple-goals-per-damos_quota-and-helpers-for-those.patch
mm-damon-sysfs-use-only-quota-goals.patch
mm-damon-core-remove-goal-field-of-damos_quota.patch
mm-damon-core-let-goal-specified-with-only-target-and-current-values.patch
mm-damon-core-support-multiple-metrics-for-quota-goal.patch
mm-damon-core-implement-psi-metric-damos-quota-goal.patch
mm-damon-sysfs-schemes-support-psi-based-quota-auto-tune.patch
docs-mm-damon-design-document-quota-goal-self-tuning.patch
docs-abi-damon-document-quota-goal-metric-file.patch
docs-admin-guide-mm-damon-usage-document-quota-goal-metric-file.patch
docs-admin-guide-mm-damon-usage-document-quota-goal-metric-file-fix.patch
mm-damon-reclaim-implement-user-feedback-driven-quota-auto-tuning.patch
mm-damon-reclaim-implement-memory-psi-driven-quota-self-tuning.patch
docs-admin-guide-mm-damon-reclaim-document-auto-tuning-parameters.patch


^ permalink raw reply	[relevance 4%]

* + maintainers-update-ocfs2-devel-mailing-list-address.patch added to mm-hotfixes-unstable branch
@ 2023-07-02 17:36  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2023-07-02 17:36 UTC (permalink / raw)
  To: mm-commits, piaojun, mark, junxiao.bi, jlbec, jiangqi903, ghe,
	gechangwei, ailiop, akpm


The patch titled
     Subject: MAINTAINERS: update ocfs2-devel mailing list address
has been added to the -mm mm-hotfixes-unstable branch.  Its filename is
     maintainers-update-ocfs2-devel-mailing-list-address.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/maintainers-update-ocfs2-devel-mailing-list-address.patch

This patch will later appear in the mm-hotfixes-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: Anthony Iliopoulos <ailiop@suse.com>
Subject: MAINTAINERS: update ocfs2-devel mailing list address
Date: Wed, 28 Jun 2023 03:34:36 +0200

The ocfs2-devel mailing list has been migrated to the kernel.org
infrastructure, update the related entry to reflect the change.

Link: https://lkml.kernel.org/r/20230628013437.47030-2-ailiop@suse.com
Signed-off-by: Anthony Iliopoulos <ailiop@suse.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Joseph Qi <jiangqi903@gmail.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Gang He <ghe@suse.com>
Cc: Jun Piao <piaojun@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 MAINTAINERS |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/MAINTAINERS~maintainers-update-ocfs2-devel-mailing-list-address
+++ a/MAINTAINERS
@@ -15899,7 +15899,7 @@ ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
 M:	Mark Fasheh <mark@fasheh.com>
 M:	Joel Becker <jlbec@evilplan.org>
 M:	Joseph Qi <joseph.qi@linux.alibaba.com>
-L:	ocfs2-devel@oss.oracle.com (moderated for non-subscribers)
+L:	ocfs2-devel@lists.linux.dev
 S:	Supported
 W:	http://ocfs2.wiki.kernel.org
 F:	Documentation/filesystems/dlmfs.rst
_

Patches currently in -mm which might be from ailiop@suse.com are

maintainers-update-ocfs2-devel-mailing-list-address.patch
docs-update-ocfs2-devel-mailing-list-address.patch


^ permalink raw reply	[relevance 5%]

* [RFC PATCH v2 4/6] coco/tsm: Introduce a class device for TEE Security Managers
  @ 2024-04-12  8:52  5% ` Dan Williams
  2024-04-12  8:51  5% ` [RFC PATCH v2 2/6] coco/guest: Move shared guest CC infrastructure to drivers/virt/coco/guest/ Dan Williams
  1 sibling, 0 replies; 200+ results
From: Dan Williams @ 2024-04-12  8:52 UTC (permalink / raw)
  To: linux-coco
  Cc: Xiaoyao Li, Isaku Yamahata, Alexey Kardashevskiy, Wu Hao,
	Yilun Xu, Tom Lendacky, John Allen, bhelgaas, kevin.tian, gregkh,
	linux-pci, lukas

A "TSM" is a platform component that provides an API for securely
provisioning resources for a confidential guest (TVM) to consume. The
name originates from the PCI specification for platform agent that
carries out operations for PCIe TDISP (TEE Device Interface Security
Protocol).

Instances of this class device are parented by a device representing the
platform security capability like CONFIG_CRYPTO_DEV_CCP or
CONFIG_INTEL_TDX_HOST.

This class device interface is a frontend to the aspects of a TSM and
TEE I/O that are cross-architecture common. This includes mechanisms
like enumerating available platform TEE I/O capabilities and
provisioning connections between the platform TSM and device DSMs
(Device Security Manager (TDISP)).

For now this is just the scaffolding for registering a TSM device sysfs
interface.

Cc: Xiaoyao Li <xiaoyao.li@intel.com>
Cc: Isaku Yamahata <isaku.yamahata@intel.com>
Cc: Alexey Kardashevskiy <aik@amd.com>
Cc: Wu Hao <hao.wu@intel.com>
Cc: Yilun Xu <yilun.xu@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: John Allen <john.allen@amd.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 MAINTAINERS                       |    3 +
 drivers/virt/coco/Kconfig         |    2 +
 drivers/virt/coco/Makefile        |    1 
 drivers/virt/coco/host/Kconfig    |    6 ++
 drivers/virt/coco/host/Makefile   |    6 ++
 drivers/virt/coco/host/tsm-core.c |  113 +++++++++++++++++++++++++++++++++++++
 include/linux/tsm.h               |    5 ++
 7 files changed, 135 insertions(+), 1 deletion(-)
 create mode 100644 drivers/virt/coco/host/Kconfig
 create mode 100644 drivers/virt/coco/host/Makefile
 create mode 100644 drivers/virt/coco/host/tsm-core.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 65beba4e704a..8d5bcd9d43ac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22461,12 +22461,13 @@ W:	https://github.com/srcres258/linux-doc
 T:	git git://github.com/srcres258/linux-doc.git doc-zh-tw
 F:	Documentation/translations/zh_TW/
 
-TRUSTED SECURITY MODULE (TSM) ATTESTATION REPORTS
+TRUSTED (TEE) SECURITY MANAGER (TSM)
 M:	Dan Williams <dan.j.williams@intel.com>
 L:	linux-coco@lists.linux.dev
 S:	Maintained
 F:	Documentation/ABI/testing/configfs-tsm
 F:	drivers/virt/coco/guest/tsm_report.c
+F:	drivers/virt/coco/host/
 F:	include/linux/tsm.h
 
 TTY LAYER AND SERIAL DRIVERS
diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig
index 7c41e0abd423..ae92da620168 100644
--- a/drivers/virt/coco/Kconfig
+++ b/drivers/virt/coco/Kconfig
@@ -10,3 +10,5 @@ source "drivers/virt/coco/sev-guest/Kconfig"
 source "drivers/virt/coco/tdx-guest/Kconfig"
 
 source "drivers/virt/coco/guest/Kconfig"
+
+source "drivers/virt/coco/host/Kconfig"
diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile
index 621111811a76..3557f556e782 100644
--- a/drivers/virt/coco/Makefile
+++ b/drivers/virt/coco/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_EFI_SECRET)	+= efi_secret/
 obj-$(CONFIG_SEV_GUEST)		+= sev-guest/
 obj-$(CONFIG_INTEL_TDX_GUEST)	+= tdx-guest/
 obj-$(CONFIG_TSM_REPORTS)	+= guest/
+obj-y				+= host/
diff --git a/drivers/virt/coco/host/Kconfig b/drivers/virt/coco/host/Kconfig
new file mode 100644
index 000000000000..4fbc6ef34f12
--- /dev/null
+++ b/drivers/virt/coco/host/Kconfig
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# TSM (TEE Security Manager) Common infrastructure and host drivers
+#
+config TSM
+	tristate
diff --git a/drivers/virt/coco/host/Makefile b/drivers/virt/coco/host/Makefile
new file mode 100644
index 000000000000..be0aba6007cd
--- /dev/null
+++ b/drivers/virt/coco/host/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# TSM (TEE Security Manager) Common infrastructure and host drivers
+
+obj-$(CONFIG_TSM) += tsm.o
+tsm-y := tsm-core.o
diff --git a/drivers/virt/coco/host/tsm-core.c b/drivers/virt/coco/host/tsm-core.c
new file mode 100644
index 000000000000..0ee738fc40ed
--- /dev/null
+++ b/drivers/virt/coco/host/tsm-core.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2024 Intel Corporation. All rights reserved. */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/tsm.h>
+#include <linux/rwsem.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/cleanup.h>
+
+static DECLARE_RWSEM(tsm_core_rwsem);
+static struct class *tsm_class;
+static struct tsm_subsys {
+	struct device dev;
+} *tsm_subsys;
+
+static struct tsm_subsys *
+alloc_tsm_subsys(struct device *parent, const struct attribute_group **groups)
+{
+	struct tsm_subsys *subsys = kzalloc(sizeof(*subsys), GFP_KERNEL);
+	struct device *dev;
+
+	if (!subsys)
+		return ERR_PTR(-ENOMEM);
+	dev = &subsys->dev;
+	dev->parent = parent;
+	dev->groups = groups;
+	dev->class = tsm_class;
+	device_initialize(dev);
+	return subsys;
+}
+
+static void put_tsm_subsys(struct tsm_subsys *subsys)
+{
+	if (!IS_ERR_OR_NULL(subsys))
+		put_device(&subsys->dev);
+}
+
+DEFINE_FREE(put_tsm_subsys, struct tsm_subsys *,
+	    if (!IS_ERR_OR_NULL(_T)) put_tsm_subsys(_T))
+struct tsm_subsys *tsm_register(struct device *parent,
+				const struct attribute_group **groups)
+{
+	struct device *dev;
+	int rc;
+
+	guard(rwsem_write)(&tsm_core_rwsem);
+	if (tsm_subsys) {
+		dev_warn(parent, "failed to register: %s already registered\n",
+			 dev_name(tsm_subsys->dev.parent));
+		return ERR_PTR(-EBUSY);
+	}
+
+	struct tsm_subsys *subsys __free(put_tsm_subsys) =
+		alloc_tsm_subsys(parent, groups);
+	if (IS_ERR(subsys))
+		return subsys;
+
+	dev = &subsys->dev;
+	rc = dev_set_name(dev, "tsm0");
+	if (rc)
+		return ERR_PTR(rc);
+
+	rc = device_add(dev);
+	if (rc)
+		return ERR_PTR(rc);
+
+	tsm_subsys = no_free_ptr(subsys);
+
+	return tsm_subsys;
+}
+EXPORT_SYMBOL_GPL(tsm_register);
+
+void tsm_unregister(struct tsm_subsys *subsys)
+{
+	guard(rwsem_write)(&tsm_core_rwsem);
+	if (!tsm_subsys || subsys != tsm_subsys) {
+		pr_warn("failed to unregister, not currently registered\n");
+		return;
+	}
+
+	device_unregister(&subsys->dev);
+	tsm_subsys = NULL;
+}
+EXPORT_SYMBOL_GPL(tsm_unregister);
+
+static void tsm_release(struct device *dev)
+{
+	struct tsm_subsys *subsys = container_of(dev, typeof(*subsys), dev);
+
+	kfree(subsys);
+}
+
+static int __init tsm_init(void)
+{
+	tsm_class = class_create("tsm");
+	if (IS_ERR(tsm_class))
+		return PTR_ERR(tsm_class);
+
+	tsm_class->dev_release = tsm_release;
+	return 0;
+}
+module_init(tsm_init)
+
+static void __exit tsm_exit(void)
+{
+	class_destroy(tsm_class);
+}
+module_exit(tsm_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TEE Security Manager core");
diff --git a/include/linux/tsm.h b/include/linux/tsm.h
index 9bbb1d130d01..2867c2ecbd11 100644
--- a/include/linux/tsm.h
+++ b/include/linux/tsm.h
@@ -4,6 +4,7 @@
 
 #include <linux/sizes.h>
 #include <linux/types.h>
+#include <linux/device.h>
 
 #define TSM_REPORT_INBLOB_MAX 64
 #define TSM_REPORT_OUTBLOB_MAX SZ_32K
@@ -66,4 +67,8 @@ extern const struct config_item_type tsm_report_extra_type;
 int tsm_report_register(const struct tsm_report_ops *ops, void *priv,
 			const struct config_item_type *type);
 int tsm_report_unregister(const struct tsm_report_ops *ops);
+struct tsm_subsys;
+struct tsm_subsys *tsm_register(struct device *parent,
+				const struct attribute_group **groups);
+void tsm_unregister(struct tsm_subsys *subsys);
 #endif /* __TSM_H */


^ permalink raw reply related	[relevance 5%]

* [PATCH v7 2/2] dt-bindings: soc: add loongson-2 chipid
  2022-11-11  5:42  5% [PATCH v7 1/2] soc: loongson: add GUTS driver for loongson-2 platforms Yinbo Zhu
@ 2022-11-11  5:42  5% ` Yinbo Zhu
  0 siblings, 0 replies; 200+ results
From: Yinbo Zhu @ 2022-11-11  5:42 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, soc, Yinbo Zhu
  Cc: Rob Herring

Add the Loongson-2 SoC chipid binding with DT schema format using
json-schema.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Change in v7:
		1. NO change, but other patch in this series of patches set	
		   has changes.
Change in v6:
		1. NO change, but other patch in this series of patches set	
		   has changes.
Change in v5:
		1. Add all history change log information.
		2. Add reviewed-by information.
Change in v4:
		1. NO change, but other patch in this series of patches set	
		   has changes.
Change in v3:
		1. Drop "driver" and describe instead what is GUTS, including
		   its acronym.
		2. Add desciption about the SoC register.
		3. Fixup dts node name.
		4. Replace string loongson2/Loongson2 with loongson-2/Loongson-2
                   in binding file and commit message.
Change in v2:
		1. NO change, but other patch in this series of patches set	
		   has changes.

 .../bindings/hwinfo/loongson,ls2k-chipid.yaml | 38 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 39 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml

diff --git a/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
new file mode 100644
index 000000000000..9d0c36ec1982
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwinfo/loongson,ls2k-chipid.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson-2 SoC ChipID
+
+maintainers:
+  - Yinbo Zhu <zhuyinbo@loongson.cn>
+
+description: |
+  Loongson-2 SoC contains many groups of global utilities register
+  blocks, of which the ChipID group registers record SoC version,
+  feature, vendor and id information.
+
+properties:
+  compatible:
+    const: loongson,ls2k-chipid
+
+  reg:
+    maxItems: 1
+
+  little-endian: true
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    chipid: chipid@1fe00000 {
+        compatible = "loongson,ls2k-chipid";
+        reg = <0x1fe00000 0x3ffc>;
+        little-endian;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 99aa2cb9c80a..0f32f2a614ae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12048,6 +12048,7 @@ LOONGSON-2 SOC SERIES GUTS DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	loongarch@lists.linux.dev
 S:	Maintained
+F:	Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
 F:	drivers/soc/loongson/loongson2_guts.c
 
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
-- 
2.20.1


^ permalink raw reply related	[relevance 5%]

* [virtio-dev] [RFC PATCH v3 4/7] virtio_rtc: Add module and driver core
    2023-12-18  7:38  5%   ` Peter Hilber
@ 2023-12-18  7:38  5%   ` Peter Hilber
  0 siblings, 0 replies; 200+ results
From: Peter Hilber @ 2023-12-18  7:38 UTC (permalink / raw)
  To: linux-kernel, virtualization, virtio-dev
  Cc: Peter Hilber, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
	Richard Cochran, netdev, Marc Zyngier, Mark Rutland,
	Daniel Lezcano, Thomas Gleixner, linux-arm-kernel, linux-rtc,
	Alessandro Zummo, Alexandre Belloni

Add the virtio_rtc module and driver core. The virtio_rtc module implements
a driver compatible with the proposed Virtio RTC device specification.
The Virtio RTC (Real Time Clock) device provides information about current
time. The device can provide different clocks, e.g. for the UTC or TAI time
standards, or for physical time elapsed since some past epoch. The driver
can read the clocks with simple or more accurate methods.

Implement the core, which interacts with the Virtio RTC device. Apart from
this, the core does not expose functionality outside of the virtio_rtc
module. A follow-up patch will expose PTP clocks.

Provide synchronous messaging, which is enough for the expected time
synchronization use cases through PTP clocks (similar to ptp_kvm) or RTC
Class driver.

Signed-off-by: Peter Hilber <peter.hilber@opensynergy.com>
---

Notes:
    v3:
    
    - merge readq and controlq into a single requestq (spec v3)
    
    - don't guard cross-timestamping with feature bit (spec v3)
    
    - pad message headers to 64 bits (spec v3)
    
    - reduce clock id to 16 bits (spec v3)
    
    - change Virtio status codes (spec v3)
    
    - use 'VIRTIO_RTC_REQ_' prefix for request messages (spec v3)

 MAINTAINERS                          |   7 +
 drivers/virtio/Kconfig               |  13 +
 drivers/virtio/Makefile              |   2 +
 drivers/virtio/virtio_rtc_driver.c   | 761 +++++++++++++++++++++++++++
 drivers/virtio/virtio_rtc_internal.h |  23 +
 include/uapi/linux/virtio_rtc.h      | 144 +++++
 6 files changed, 950 insertions(+)
 create mode 100644 drivers/virtio/virtio_rtc_driver.c
 create mode 100644 drivers/virtio/virtio_rtc_internal.h
 create mode 100644 include/uapi/linux/virtio_rtc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index b589218605b4..0c157a19bbfd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23200,6 +23200,13 @@ S:	Maintained
 F:	drivers/nvdimm/nd_virtio.c
 F:	drivers/nvdimm/virtio_pmem.c
 
+VIRTIO RTC DRIVER
+M:	Peter Hilber <peter.hilber@opensynergy.com>
+L:	virtualization@lists.linux.dev
+S:	Maintained
+F:	drivers/virtio/virtio_rtc_*
+F:	include/uapi/linux/virtio_rtc.h
+
 VIRTIO SOUND DRIVER
 M:	Anton Yakovlev <anton.yakovlev@opensynergy.com>
 M:	"Michael S. Tsirkin" <mst@redhat.com>
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 0a53a61231c2..834dd14bc070 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -173,4 +173,17 @@ config VIRTIO_DMA_SHARED_BUFFER
 	 This option adds a flavor of dma buffers that are backed by
 	 virtio resources.
 
+config VIRTIO_RTC
+	tristate "Virtio RTC driver"
+	depends on VIRTIO
+	depends on PTP_1588_CLOCK_OPTIONAL
+	help
+	 This driver provides current time from a Virtio RTC device. The driver
+	 provides the time through one or more clocks.
+
+	 To compile this code as a module, choose M here: the module will be
+	 called virtio_rtc.
+
+	 If unsure, say M.
+
 endif # VIRTIO_MENU
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 8e98d24917cc..f760414ed6ab 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -12,3 +12,5 @@ obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o
 obj-$(CONFIG_VIRTIO_VDPA) += virtio_vdpa.o
 obj-$(CONFIG_VIRTIO_MEM) += virtio_mem.o
 obj-$(CONFIG_VIRTIO_DMA_SHARED_BUFFER) += virtio_dma_buf.o
+obj-$(CONFIG_VIRTIO_RTC) += virtio_rtc.o
+virtio_rtc-y := virtio_rtc_driver.o
diff --git a/drivers/virtio/virtio_rtc_driver.c b/drivers/virtio/virtio_rtc_driver.c
new file mode 100644
index 000000000000..ef1ea14b3bec
--- /dev/null
+++ b/drivers/virtio/virtio_rtc_driver.c
@@ -0,0 +1,761 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * virtio_rtc driver core
+ *
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ */
+
+#include <linux/completion.h>
+#include <linux/virtio.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+#include <linux/module.h>
+
+#include <uapi/linux/virtio_rtc.h>
+
+#include "virtio_rtc_internal.h"
+
+/* virtqueue order */
+enum {
+	VIORTC_REQUESTQ,
+	VIORTC_MAX_NR_QUEUES,
+};
+
+/**
+ * struct viortc_vq - virtqueue abstraction
+ * @vq: virtqueue
+ * @lock: protects access to vq
+ */
+struct viortc_vq {
+	struct virtqueue *vq;
+	spinlock_t lock;
+};
+
+/**
+ * struct viortc_dev - virtio_rtc device data
+ * @vdev: virtio device
+ * @vqs: virtqueues
+ * @num_clocks: # of virtio_rtc clocks
+ */
+struct viortc_dev {
+	struct virtio_device *vdev;
+	struct viortc_vq vqs[VIORTC_MAX_NR_QUEUES];
+	u16 num_clocks;
+};
+
+/**
+ * struct viortc_msg - Message requested by driver, responded by device.
+ * @viortc: device data
+ * @req: request buffer
+ * @resp: response buffer
+ * @responded: vqueue callback signals response reception
+ * @refcnt: Message reference count, message and buffers will be deallocated
+ *	    once 0. refcnt is decremented in the vqueue callback and in the
+ *	    thread waiting on the responded completion.
+ *          If a message response wait function times out, the message will be
+ *          freed upon late reception (refcnt will reach 0 in the callback), or
+ *          device removal.
+ * @req_size: size of request in bytes
+ * @resp_cap: maximum size of response in bytes
+ * @resp_actual_size: actual size of response
+ */
+struct viortc_msg {
+	struct viortc_dev *viortc;
+	void *req;
+	void *resp;
+	struct completion responded;
+	refcount_t refcnt;
+	unsigned int req_size;
+	unsigned int resp_cap;
+	unsigned int resp_actual_size;
+};
+
+/**
+ * viortc_msg_init() - Allocate and initialize requestq message.
+ * @viortc: device data
+ * @msg_type: virtio_rtc message type
+ * @req_size: size of request buffer to be allocated
+ * @resp_cap: size of response buffer to be allocated
+ *
+ * Initializes the message refcnt to 2. The refcnt will be decremented once in
+ * the virtqueue callback, and once in the thread waiting on the message (on
+ * completion or timeout).
+ *
+ * Context: Process context.
+ * Return: non-NULL on success.
+ */
+static struct viortc_msg *viortc_msg_init(struct viortc_dev *viortc,
+					  u16 msg_type, unsigned int req_size,
+					  unsigned int resp_cap)
+{
+	struct viortc_msg *msg;
+	struct device *dev = &viortc->vdev->dev;
+	struct virtio_rtc_req_head *req_head;
+
+	msg = devm_kzalloc(dev, sizeof(*msg), GFP_KERNEL);
+	if (!msg)
+		return NULL;
+
+	init_completion(&msg->responded);
+
+	msg->req = devm_kzalloc(dev, req_size, GFP_KERNEL);
+	if (!msg->req)
+		goto err_free_msg;
+
+	req_head = msg->req;
+
+	msg->resp = devm_kzalloc(dev, resp_cap, GFP_KERNEL);
+	if (!msg->resp)
+		goto err_free_msg_req;
+
+	msg->viortc = viortc;
+	msg->req_size = req_size;
+	msg->resp_cap = resp_cap;
+
+	refcount_set(&msg->refcnt, 2);
+
+	req_head->msg_type = virtio_cpu_to_le(msg_type, req_head->msg_type);
+
+	return msg;
+
+err_free_msg_req:
+	devm_kfree(dev, msg->req);
+
+err_free_msg:
+	devm_kfree(dev, msg);
+
+	return NULL;
+}
+
+/**
+ * viortc_msg_release() - Decrement message refcnt, potentially free message.
+ * @msg: message requested by driver
+ *
+ * Context: Any context.
+ */
+static void viortc_msg_release(struct viortc_msg *msg)
+{
+	if (refcount_dec_and_test(&msg->refcnt)) {
+		struct device *dev = &msg->viortc->vdev->dev;
+
+		devm_kfree(dev, msg->req);
+		devm_kfree(dev, msg->resp);
+		devm_kfree(dev, msg);
+	}
+}
+
+/**
+ * viortc_do_cb() - generic virtqueue callback logic
+ * @vq: virtqueue
+ * @handle_buf: function to process a used buffer
+ *
+ * Context: virtqueue callback, typically interrupt. Takes and releases vq lock.
+ */
+static void viortc_do_cb(struct virtqueue *vq,
+			 void (*handle_buf)(void *token, unsigned int len,
+					    struct virtqueue *vq,
+					    struct viortc_vq *viortc_vq,
+					    struct viortc_dev *viortc))
+{
+	struct viortc_dev *viortc = vq->vdev->priv;
+	struct viortc_vq *viortc_vq;
+	bool cb_enabled = true;
+	unsigned long flags;
+	spinlock_t *lock;
+	unsigned int len;
+	void *token;
+
+	viortc_vq = &viortc->vqs[vq->index];
+	lock = &viortc_vq->lock;
+
+	for (;;) {
+		spin_lock_irqsave(lock, flags);
+
+		if (cb_enabled) {
+			virtqueue_disable_cb(vq);
+			cb_enabled = false;
+		}
+
+		token = virtqueue_get_buf(vq, &len);
+		if (!token) {
+			if (virtqueue_enable_cb(vq)) {
+				spin_unlock_irqrestore(lock, flags);
+				return;
+			}
+			cb_enabled = true;
+		}
+
+		spin_unlock_irqrestore(lock, flags);
+
+		if (token)
+			handle_buf(token, len, vq, viortc_vq, viortc);
+	}
+}
+
+/**
+ * viortc_requestq_hdlr() - process a requestq used buffer
+ * @token: token identifying the buffer
+ * @len: bytes written by device
+ * @vq: virtqueue
+ * @viortc_vq: device specific data for virtqueue
+ * @viortc: device data
+ *
+ * Signals completion for each received message.
+ *
+ * Context: virtqueue callback
+ */
+static void viortc_requestq_hdlr(void *token, unsigned int len,
+				 struct virtqueue *vq,
+				 struct viortc_vq *viortc_vq,
+				 struct viortc_dev *viortc)
+{
+	struct viortc_msg *msg = token;
+
+	msg->resp_actual_size = len;
+
+	/*
+	 * completion waiter must see our msg metadata, but complete() does not
+	 * guarantee a memory barrier
+	 */
+	smp_wmb();
+
+	complete(&msg->responded);
+	viortc_msg_release(msg);
+}
+
+/**
+ * viortc_cb_requestq() - callback for requestq
+ * @vq: virtqueue
+ *
+ * Context: virtqueue callback
+ */
+static void viortc_cb_requestq(struct virtqueue *vq)
+{
+	viortc_do_cb(vq, viortc_requestq_hdlr);
+}
+
+/**
+ * viortc_get_resp_errno() - converts virtio_rtc errnos to system errnos
+ * @resp_head: message response header
+ *
+ * Return: negative system errno, or 0
+ */
+static int viortc_get_resp_errno(struct virtio_rtc_resp_head *resp_head)
+{
+	switch (virtio_le_to_cpu(resp_head->status)) {
+	case VIRTIO_RTC_S_OK:
+		return 0;
+	case VIRTIO_RTC_S_EOPNOTSUPP:
+		return -EOPNOTSUPP;
+	case VIRTIO_RTC_S_EINVAL:
+		return -EINVAL;
+	case VIRTIO_RTC_S_ENODEV:
+		return -ENODEV;
+	case VIRTIO_RTC_S_EIO:
+	default:
+		return -EIO;
+	}
+}
+
+/**
+ * viortc_msg_xfer() - send message request, wait until message response
+ * @vq: virtqueue
+ * @msg: message with driver request
+ * @timeout_jiffies: message response timeout, 0 for no timeout
+ *
+ * Context: Process context. Takes and releases vq.lock. May sleep.
+ */
+static int viortc_msg_xfer(struct viortc_vq *vq, struct viortc_msg *msg,
+			   unsigned long timeout_jiffies)
+{
+	int ret;
+	unsigned long flags;
+	struct scatterlist out_sg[1];
+	struct scatterlist in_sg[1];
+	struct scatterlist *sgs[2] = { out_sg, in_sg };
+	bool notify;
+
+	sg_init_one(out_sg, msg->req, msg->req_size);
+	sg_init_one(in_sg, msg->resp, msg->resp_cap);
+
+	spin_lock_irqsave(&vq->lock, flags);
+
+	ret = virtqueue_add_sgs(vq->vq, sgs, 1, 1, msg, GFP_ATOMIC);
+	if (ret) {
+		spin_unlock_irqrestore(&vq->lock, flags);
+		/*
+		 * Release in place of the response callback, which will never
+		 * come.
+		 */
+		viortc_msg_release(msg);
+		return ret;
+	}
+
+	notify = virtqueue_kick_prepare(vq->vq);
+
+	spin_unlock_irqrestore(&vq->lock, flags);
+
+	if (notify)
+		virtqueue_notify(vq->vq);
+
+	if (timeout_jiffies) {
+		long timeout_ret;
+
+		timeout_ret = wait_for_completion_interruptible_timeout(
+			&msg->responded, timeout_jiffies);
+
+		if (!timeout_ret)
+			return -ETIMEDOUT;
+		else if (timeout_ret < 0)
+			return (int)timeout_ret;
+	} else {
+		ret = wait_for_completion_interruptible(&msg->responded);
+		if (ret)
+			return ret;
+	}
+
+	/*
+	 * Ensure we can read message metadata written in the virtqueue
+	 * callback.
+	 */
+	smp_rmb();
+
+	/*
+	 * There is not yet a case where returning a short message would make
+	 * sense, so consider any deviation an error.
+	 */
+	if (msg->resp_actual_size != msg->resp_cap)
+		return -EINVAL;
+
+	return viortc_get_resp_errno(msg->resp);
+}
+
+/*
+ * common message handle macros for messages of different types
+ */
+
+/**
+ * VIORTC_DECLARE_MSG_HDL_ONSTACK() - declare message handle on stack
+ * @hdl: message handle name
+ * @msg_suf_lowerc: message type suffix in lowercase
+ * @msg_suf_upperc: message type suffix in uppercase
+ */
+#define VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, msg_suf_lowerc, msg_suf_upperc) \
+	struct {                                                            \
+		struct viortc_msg *msg;                                     \
+		struct virtio_rtc_req_##msg_suf_lowerc *req;                \
+		struct virtio_rtc_resp_##msg_suf_lowerc *resp;              \
+		unsigned int req_size;                                      \
+		unsigned int resp_cap;                                      \
+		u16 msg_type;                                               \
+	} hdl = {                                                           \
+		NULL,                                                       \
+		NULL,                                                       \
+		NULL,                                                       \
+		sizeof(struct virtio_rtc_req_##msg_suf_lowerc),             \
+		sizeof(struct virtio_rtc_resp_##msg_suf_lowerc),            \
+		VIRTIO_RTC_REQ_##msg_suf_upperc,                            \
+	}
+
+/**
+ * VIORTC_MSG() - extract message from message handle
+ *
+ * Return: struct viortc_msg
+ */
+#define VIORTC_MSG(hdl) ((hdl).msg)
+
+/**
+ * VIORTC_MSG_INIT() - initialize message handle
+ * @hdl: message handle
+ * @viortc: device data (struct viortc_dev *)
+ *
+ * Context: Process context.
+ * Return: 0 on success, -ENOMEM otherwise.
+ */
+#define VIORTC_MSG_INIT(hdl, viortc)                                         \
+	({                                                                   \
+		typeof(hdl) *_hdl = &(hdl);                                  \
+									     \
+		_hdl->msg = viortc_msg_init((viortc), _hdl->msg_type,        \
+					    _hdl->req_size, _hdl->resp_cap); \
+		if (_hdl->msg) {                                             \
+			_hdl->req = _hdl->msg->req;                          \
+			_hdl->resp = _hdl->msg->resp;                        \
+		}                                                            \
+		_hdl->msg ? 0 : -ENOMEM;                                     \
+	})
+
+/**
+ * VIORTC_MSG_WRITE() - write a request message field
+ * @hdl: message handle
+ * @dest_member: request message field name
+ * @src_ptr: pointer to data of compatible type
+ *
+ * Writes the field in little-endian format.
+ */
+#define VIORTC_MSG_WRITE(hdl, dest_member, src_ptr)                         \
+	do {                                                                \
+		typeof(hdl) _hdl = (hdl);                                   \
+		typeof(src_ptr) _src_ptr = (src_ptr);                       \
+									    \
+		/* Sanity check: must match the member's type */            \
+		typecheck(typeof(_hdl.req->dest_member), *_src_ptr);        \
+									    \
+		_hdl.req->dest_member =                                     \
+			virtio_cpu_to_le(*_src_ptr, _hdl.req->dest_member); \
+	} while (0)
+
+/**
+ * VIORTC_MSG_READ() - read from a response message field
+ * @hdl: message handle
+ * @src_member: response message field name
+ * @dest_ptr: pointer to data of compatible type
+ *
+ * Converts from little-endian format and writes to dest_ptr.
+ */
+#define VIORTC_MSG_READ(hdl, src_member, dest_ptr)                     \
+	do {                                                           \
+		typeof(dest_ptr) _dest_ptr = (dest_ptr);               \
+								       \
+		/* Sanity check: must match the member's type */       \
+		typecheck(typeof((hdl).resp->src_member), *_dest_ptr); \
+								       \
+		*_dest_ptr = virtio_le_to_cpu((hdl).resp->src_member); \
+	} while (0)
+
+/*
+ * read requests
+ */
+
+/** timeout for clock readings, where timeouts are considered non-fatal */
+#define VIORTC_MSG_READ_TIMEOUT (msecs_to_jiffies(60 * 1000))
+
+/**
+ * viortc_read() - VIRTIO_RTC_REQ_READ wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @reading: clock reading [ns]
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_read(struct viortc_dev *viortc, u16 vio_clk_id, u64 *reading)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, read, READ);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      VIORTC_MSG_READ_TIMEOUT);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, clock_reading, reading);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_read_cross() - VIRTIO_RTC_REQ_READ_CROSS wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @hw_counter: virtio_rtc HW counter type
+ * @reading: clock reading [ns]
+ * @cycles: HW counter cycles during clock reading
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_read_cross(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		      u64 *reading, u64 *cycles)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, read_cross, READ_CROSS);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+	VIORTC_MSG_WRITE(hdl, hw_counter, &hw_counter);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      VIORTC_MSG_READ_TIMEOUT);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, clock_reading, reading);
+	VIORTC_MSG_READ(hdl, counter_cycles, cycles);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/*
+ * control requests
+ */
+
+/**
+ * viortc_cfg() - VIRTIO_RTC_REQ_CFG wrapper
+ * @viortc: device data
+ * @num_clocks: # of virtio_rtc clocks
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_cfg(struct viortc_dev *viortc, u16 *num_clocks)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, cfg, CFG);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, num_clocks, num_clocks);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_clock_cap() - VIRTIO_RTC_REQ_CLOCK_CAP wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @type: virtio_rtc clock type
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_clock_cap(struct viortc_dev *viortc, u16 vio_clk_id,
+			    u16 *type)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, clock_cap, CLOCK_CAP);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, type, type);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_cross_cap() - VIRTIO_RTC_REQ_CROSS_CAP wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @hw_counter: virtio_rtc HW counter type
+ * @supported: xtstamping is supported for the vio_clk_id/hw_counter pair
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_cross_cap(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		     bool *supported)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, cross_cap, CROSS_CAP);
+	u8 flags;
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+	VIORTC_MSG_WRITE(hdl, hw_counter, &hw_counter);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, flags, &flags);
+	*supported = !!(flags & VIRTIO_RTC_FLAG_CROSS_CAP);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/*
+ * init, deinit
+ */
+
+/**
+ * viortc_clocks_init() - init local representations of virtio_rtc clocks
+ * @viortc: device data
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_clocks_init(struct viortc_dev *viortc)
+{
+	int ret;
+	u16 num_clocks;
+
+	ret = viortc_cfg(viortc, &num_clocks);
+	if (ret)
+		return ret;
+
+	if (num_clocks < 1) {
+		dev_err(&viortc->vdev->dev, "device reported 0 clocks\n");
+		return -ENODEV;
+	}
+
+	viortc->num_clocks = num_clocks;
+
+	/* In the future, PTP clocks will be initialized here. */
+	(void)viortc_clock_cap;
+
+	return ret;
+}
+
+/**
+ * viortc_init_vqs() - init virtqueues
+ * @viortc: device data
+ *
+ * Inits virtqueues and associated data.
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_init_vqs(struct viortc_dev *viortc)
+{
+	int ret;
+	struct virtio_device *vdev = viortc->vdev;
+	const char *names[VIORTC_MAX_NR_QUEUES];
+	vq_callback_t *callbacks[VIORTC_MAX_NR_QUEUES];
+	struct virtqueue *vqs[VIORTC_MAX_NR_QUEUES];
+	int nr_queues;
+
+	nr_queues = VIORTC_REQUESTQ + 1;
+	names[VIORTC_REQUESTQ] = "requestq";
+	callbacks[VIORTC_REQUESTQ] = viortc_cb_requestq;
+
+	ret = virtio_find_vqs(vdev, nr_queues, vqs, callbacks, names, NULL);
+	if (ret)
+		return ret;
+
+	viortc->vqs[VIORTC_REQUESTQ].vq = vqs[VIORTC_REQUESTQ];
+	spin_lock_init(&viortc->vqs[VIORTC_REQUESTQ].lock);
+
+	return 0;
+}
+
+/**
+ * viortc_probe() - probe a virtio_rtc virtio device
+ * @vdev: virtio device
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_probe(struct virtio_device *vdev)
+{
+	struct viortc_dev *viortc;
+	int ret;
+
+	viortc = devm_kzalloc(&vdev->dev, sizeof(*viortc), GFP_KERNEL);
+	if (!viortc)
+		return -ENOMEM;
+
+	vdev->priv = viortc;
+	viortc->vdev = vdev;
+
+	ret = viortc_init_vqs(viortc);
+	if (ret)
+		return ret;
+
+	virtio_device_ready(vdev);
+
+	/* Ready vdev for use by frontend devices initialized next. */
+	smp_wmb();
+
+	ret = viortc_clocks_init(viortc);
+	if (ret)
+		goto err_reset_vdev;
+
+	return 0;
+
+err_reset_vdev:
+	virtio_reset_device(vdev);
+	vdev->config->del_vqs(vdev);
+
+	return ret;
+}
+
+/**
+ * viortc_remove() - remove a virtio_rtc virtio device
+ * @vdev: virtio device
+ */
+static void viortc_remove(struct virtio_device *vdev)
+{
+	/* In the future, PTP clocks will be deinitialized here. */
+
+	virtio_reset_device(vdev);
+	vdev->config->del_vqs(vdev);
+}
+
+static struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_CLOCK, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+MODULE_DEVICE_TABLE(virtio, id_table);
+
+static struct virtio_driver virtio_rtc_drv = {
+	.driver.name = KBUILD_MODNAME,
+	.driver.owner = THIS_MODULE,
+	.id_table = id_table,
+	.probe = viortc_probe,
+	.remove = viortc_remove,
+};
+
+module_virtio_driver(virtio_rtc_drv);
+
+MODULE_DESCRIPTION("Virtio RTC driver");
+MODULE_AUTHOR("OpenSynergy GmbH");
+MODULE_LICENSE("GPL");
diff --git a/drivers/virtio/virtio_rtc_internal.h b/drivers/virtio/virtio_rtc_internal.h
new file mode 100644
index 000000000000..9267661b8030
--- /dev/null
+++ b/drivers/virtio/virtio_rtc_internal.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * virtio_rtc internal interfaces
+ *
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ */
+
+#ifndef _VIRTIO_RTC_INTERNAL_H_
+#define _VIRTIO_RTC_INTERNAL_H_
+
+#include <linux/types.h>
+
+/* driver core IFs */
+
+struct viortc_dev;
+
+int viortc_read(struct viortc_dev *viortc, u16 vio_clk_id, u64 *reading);
+int viortc_read_cross(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		      u64 *reading, u64 *cycles);
+int viortc_cross_cap(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		     bool *supported);
+
+#endif /* _VIRTIO_RTC_INTERNAL_H_ */
diff --git a/include/uapi/linux/virtio_rtc.h b/include/uapi/linux/virtio_rtc.h
new file mode 100644
index 000000000000..f469276562d7
--- /dev/null
+++ b/include/uapi/linux/virtio_rtc.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */
+/*
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ */
+
+#ifndef _LINUX_VIRTIO_RTC_H
+#define _LINUX_VIRTIO_RTC_H
+
+#include <linux/types.h>
+
+/* read request message types */
+
+#define VIRTIO_RTC_REQ_READ 0x0001
+#define VIRTIO_RTC_REQ_READ_CROSS 0x0002
+
+/* control request message types */
+
+#define VIRTIO_RTC_REQ_CFG 0x1000
+#define VIRTIO_RTC_REQ_CLOCK_CAP 0x1001
+#define VIRTIO_RTC_REQ_CROSS_CAP 0x1002
+
+/* Message headers */
+
+/** common request header */
+struct virtio_rtc_req_head {
+	__le16 msg_type;
+	__u8 reserved[6];
+};
+
+/** common response header */
+struct virtio_rtc_resp_head {
+#define VIRTIO_RTC_S_OK 0
+#define VIRTIO_RTC_S_EOPNOTSUPP 2
+#define VIRTIO_RTC_S_ENODEV 3
+#define VIRTIO_RTC_S_EINVAL 4
+#define VIRTIO_RTC_S_EIO 5
+	__u8 status;
+	__u8 reserved[7];
+};
+
+/* read requests */
+
+/* VIRTIO_RTC_REQ_READ message */
+
+struct virtio_rtc_req_read {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__u8 reserved[6];
+};
+
+struct virtio_rtc_resp_read {
+	struct virtio_rtc_resp_head head;
+	__le64 clock_reading;
+};
+
+/* VIRTIO_RTC_REQ_READ_CROSS message */
+
+struct virtio_rtc_req_read_cross {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+/** Arm Generic Timer Virtual Count */
+#define VIRTIO_RTC_COUNTER_ARM_VIRT 0
+/** Arm Generic Timer Physical Count */
+#define VIRTIO_RTC_COUNTER_ARM_PHYS 1
+/** x86 Time Stamp Counter */
+#define VIRTIO_RTC_COUNTER_X86_TSC 2
+	__le16 hw_counter;
+	__u8 reserved[4];
+};
+
+struct virtio_rtc_resp_read_cross {
+	struct virtio_rtc_resp_head head;
+	__le64 clock_reading;
+	__le64 counter_cycles;
+};
+
+/* control requests */
+
+/* VIRTIO_RTC_REQ_CFG message */
+
+struct virtio_rtc_req_cfg {
+	struct virtio_rtc_req_head head;
+	/* no request params */
+};
+
+struct virtio_rtc_resp_cfg {
+	struct virtio_rtc_resp_head head;
+	/** # of clocks -> clock ids < num_clocks are valid */
+	__le16 num_clocks;
+	__u8 reserved[6];
+};
+
+/* VIRTIO_RTC_REQ_CLOCK_CAP message */
+
+struct virtio_rtc_req_clock_cap {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__u8 reserved[6];
+};
+
+struct virtio_rtc_resp_clock_cap {
+	struct virtio_rtc_resp_head head;
+#define VIRTIO_RTC_CLOCK_UTC 0
+#define VIRTIO_RTC_CLOCK_TAI 1
+#define VIRTIO_RTC_CLOCK_MONO 2
+	__le16 type;
+	__u8 reserved[6];
+};
+
+/* VIRTIO_RTC_REQ_CROSS_CAP message */
+
+struct virtio_rtc_req_cross_cap {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__le16 hw_counter;
+	__u8 reserved[4];
+};
+
+struct virtio_rtc_resp_cross_cap {
+	struct virtio_rtc_resp_head head;
+#define VIRTIO_RTC_FLAG_CROSS_CAP (1 << 0)
+	__u8 flags;
+	__u8 reserved[7];
+};
+
+/** Union of request types for requestq */
+union virtio_rtc_req_requestq {
+	struct virtio_rtc_req_read read;
+	struct virtio_rtc_req_read_cross read_cross;
+	struct virtio_rtc_req_cfg cfg;
+	struct virtio_rtc_req_clock_cap clock_cap;
+	struct virtio_rtc_req_cross_cap cross_cap;
+};
+
+/** Union of response types for requestq */
+union virtio_rtc_resp_requestq {
+	struct virtio_rtc_resp_read read;
+	struct virtio_rtc_resp_read_cross read_cross;
+	struct virtio_rtc_resp_cfg cfg;
+	struct virtio_rtc_resp_clock_cap clock_cap;
+	struct virtio_rtc_resp_cross_cap cross_cap;
+};
+
+#endif /* _LINUX_VIRTIO_RTC_H */
-- 
2.40.1


---------------------------------------------------------------------
To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org


^ permalink raw reply related	[relevance 5%]

* [RFC PATCH v3 4/7] virtio_rtc: Add module and driver core
@ 2023-12-18  7:38  5%   ` Peter Hilber
  0 siblings, 0 replies; 200+ results
From: Peter Hilber @ 2023-12-18  7:38 UTC (permalink / raw)
  To: linux-kernel, virtualization, virtio-dev
  Cc: Peter Hilber, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
	Richard Cochran, netdev, Marc Zyngier, Mark Rutland,
	Daniel Lezcano, Thomas Gleixner, linux-arm-kernel, linux-rtc,
	Alessandro Zummo, Alexandre Belloni

Add the virtio_rtc module and driver core. The virtio_rtc module implements
a driver compatible with the proposed Virtio RTC device specification.
The Virtio RTC (Real Time Clock) device provides information about current
time. The device can provide different clocks, e.g. for the UTC or TAI time
standards, or for physical time elapsed since some past epoch. The driver
can read the clocks with simple or more accurate methods.

Implement the core, which interacts with the Virtio RTC device. Apart from
this, the core does not expose functionality outside of the virtio_rtc
module. A follow-up patch will expose PTP clocks.

Provide synchronous messaging, which is enough for the expected time
synchronization use cases through PTP clocks (similar to ptp_kvm) or RTC
Class driver.

Signed-off-by: Peter Hilber <peter.hilber@opensynergy.com>
---

Notes:
    v3:
    
    - merge readq and controlq into a single requestq (spec v3)
    
    - don't guard cross-timestamping with feature bit (spec v3)
    
    - pad message headers to 64 bits (spec v3)
    
    - reduce clock id to 16 bits (spec v3)
    
    - change Virtio status codes (spec v3)
    
    - use 'VIRTIO_RTC_REQ_' prefix for request messages (spec v3)

 MAINTAINERS                          |   7 +
 drivers/virtio/Kconfig               |  13 +
 drivers/virtio/Makefile              |   2 +
 drivers/virtio/virtio_rtc_driver.c   | 761 +++++++++++++++++++++++++++
 drivers/virtio/virtio_rtc_internal.h |  23 +
 include/uapi/linux/virtio_rtc.h      | 144 +++++
 6 files changed, 950 insertions(+)
 create mode 100644 drivers/virtio/virtio_rtc_driver.c
 create mode 100644 drivers/virtio/virtio_rtc_internal.h
 create mode 100644 include/uapi/linux/virtio_rtc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index b589218605b4..0c157a19bbfd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23200,6 +23200,13 @@ S:	Maintained
 F:	drivers/nvdimm/nd_virtio.c
 F:	drivers/nvdimm/virtio_pmem.c
 
+VIRTIO RTC DRIVER
+M:	Peter Hilber <peter.hilber@opensynergy.com>
+L:	virtualization@lists.linux.dev
+S:	Maintained
+F:	drivers/virtio/virtio_rtc_*
+F:	include/uapi/linux/virtio_rtc.h
+
 VIRTIO SOUND DRIVER
 M:	Anton Yakovlev <anton.yakovlev@opensynergy.com>
 M:	"Michael S. Tsirkin" <mst@redhat.com>
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 0a53a61231c2..834dd14bc070 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -173,4 +173,17 @@ config VIRTIO_DMA_SHARED_BUFFER
 	 This option adds a flavor of dma buffers that are backed by
 	 virtio resources.
 
+config VIRTIO_RTC
+	tristate "Virtio RTC driver"
+	depends on VIRTIO
+	depends on PTP_1588_CLOCK_OPTIONAL
+	help
+	 This driver provides current time from a Virtio RTC device. The driver
+	 provides the time through one or more clocks.
+
+	 To compile this code as a module, choose M here: the module will be
+	 called virtio_rtc.
+
+	 If unsure, say M.
+
 endif # VIRTIO_MENU
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 8e98d24917cc..f760414ed6ab 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -12,3 +12,5 @@ obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o
 obj-$(CONFIG_VIRTIO_VDPA) += virtio_vdpa.o
 obj-$(CONFIG_VIRTIO_MEM) += virtio_mem.o
 obj-$(CONFIG_VIRTIO_DMA_SHARED_BUFFER) += virtio_dma_buf.o
+obj-$(CONFIG_VIRTIO_RTC) += virtio_rtc.o
+virtio_rtc-y := virtio_rtc_driver.o
diff --git a/drivers/virtio/virtio_rtc_driver.c b/drivers/virtio/virtio_rtc_driver.c
new file mode 100644
index 000000000000..ef1ea14b3bec
--- /dev/null
+++ b/drivers/virtio/virtio_rtc_driver.c
@@ -0,0 +1,761 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * virtio_rtc driver core
+ *
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ */
+
+#include <linux/completion.h>
+#include <linux/virtio.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+#include <linux/module.h>
+
+#include <uapi/linux/virtio_rtc.h>
+
+#include "virtio_rtc_internal.h"
+
+/* virtqueue order */
+enum {
+	VIORTC_REQUESTQ,
+	VIORTC_MAX_NR_QUEUES,
+};
+
+/**
+ * struct viortc_vq - virtqueue abstraction
+ * @vq: virtqueue
+ * @lock: protects access to vq
+ */
+struct viortc_vq {
+	struct virtqueue *vq;
+	spinlock_t lock;
+};
+
+/**
+ * struct viortc_dev - virtio_rtc device data
+ * @vdev: virtio device
+ * @vqs: virtqueues
+ * @num_clocks: # of virtio_rtc clocks
+ */
+struct viortc_dev {
+	struct virtio_device *vdev;
+	struct viortc_vq vqs[VIORTC_MAX_NR_QUEUES];
+	u16 num_clocks;
+};
+
+/**
+ * struct viortc_msg - Message requested by driver, responded by device.
+ * @viortc: device data
+ * @req: request buffer
+ * @resp: response buffer
+ * @responded: vqueue callback signals response reception
+ * @refcnt: Message reference count, message and buffers will be deallocated
+ *	    once 0. refcnt is decremented in the vqueue callback and in the
+ *	    thread waiting on the responded completion.
+ *          If a message response wait function times out, the message will be
+ *          freed upon late reception (refcnt will reach 0 in the callback), or
+ *          device removal.
+ * @req_size: size of request in bytes
+ * @resp_cap: maximum size of response in bytes
+ * @resp_actual_size: actual size of response
+ */
+struct viortc_msg {
+	struct viortc_dev *viortc;
+	void *req;
+	void *resp;
+	struct completion responded;
+	refcount_t refcnt;
+	unsigned int req_size;
+	unsigned int resp_cap;
+	unsigned int resp_actual_size;
+};
+
+/**
+ * viortc_msg_init() - Allocate and initialize requestq message.
+ * @viortc: device data
+ * @msg_type: virtio_rtc message type
+ * @req_size: size of request buffer to be allocated
+ * @resp_cap: size of response buffer to be allocated
+ *
+ * Initializes the message refcnt to 2. The refcnt will be decremented once in
+ * the virtqueue callback, and once in the thread waiting on the message (on
+ * completion or timeout).
+ *
+ * Context: Process context.
+ * Return: non-NULL on success.
+ */
+static struct viortc_msg *viortc_msg_init(struct viortc_dev *viortc,
+					  u16 msg_type, unsigned int req_size,
+					  unsigned int resp_cap)
+{
+	struct viortc_msg *msg;
+	struct device *dev = &viortc->vdev->dev;
+	struct virtio_rtc_req_head *req_head;
+
+	msg = devm_kzalloc(dev, sizeof(*msg), GFP_KERNEL);
+	if (!msg)
+		return NULL;
+
+	init_completion(&msg->responded);
+
+	msg->req = devm_kzalloc(dev, req_size, GFP_KERNEL);
+	if (!msg->req)
+		goto err_free_msg;
+
+	req_head = msg->req;
+
+	msg->resp = devm_kzalloc(dev, resp_cap, GFP_KERNEL);
+	if (!msg->resp)
+		goto err_free_msg_req;
+
+	msg->viortc = viortc;
+	msg->req_size = req_size;
+	msg->resp_cap = resp_cap;
+
+	refcount_set(&msg->refcnt, 2);
+
+	req_head->msg_type = virtio_cpu_to_le(msg_type, req_head->msg_type);
+
+	return msg;
+
+err_free_msg_req:
+	devm_kfree(dev, msg->req);
+
+err_free_msg:
+	devm_kfree(dev, msg);
+
+	return NULL;
+}
+
+/**
+ * viortc_msg_release() - Decrement message refcnt, potentially free message.
+ * @msg: message requested by driver
+ *
+ * Context: Any context.
+ */
+static void viortc_msg_release(struct viortc_msg *msg)
+{
+	if (refcount_dec_and_test(&msg->refcnt)) {
+		struct device *dev = &msg->viortc->vdev->dev;
+
+		devm_kfree(dev, msg->req);
+		devm_kfree(dev, msg->resp);
+		devm_kfree(dev, msg);
+	}
+}
+
+/**
+ * viortc_do_cb() - generic virtqueue callback logic
+ * @vq: virtqueue
+ * @handle_buf: function to process a used buffer
+ *
+ * Context: virtqueue callback, typically interrupt. Takes and releases vq lock.
+ */
+static void viortc_do_cb(struct virtqueue *vq,
+			 void (*handle_buf)(void *token, unsigned int len,
+					    struct virtqueue *vq,
+					    struct viortc_vq *viortc_vq,
+					    struct viortc_dev *viortc))
+{
+	struct viortc_dev *viortc = vq->vdev->priv;
+	struct viortc_vq *viortc_vq;
+	bool cb_enabled = true;
+	unsigned long flags;
+	spinlock_t *lock;
+	unsigned int len;
+	void *token;
+
+	viortc_vq = &viortc->vqs[vq->index];
+	lock = &viortc_vq->lock;
+
+	for (;;) {
+		spin_lock_irqsave(lock, flags);
+
+		if (cb_enabled) {
+			virtqueue_disable_cb(vq);
+			cb_enabled = false;
+		}
+
+		token = virtqueue_get_buf(vq, &len);
+		if (!token) {
+			if (virtqueue_enable_cb(vq)) {
+				spin_unlock_irqrestore(lock, flags);
+				return;
+			}
+			cb_enabled = true;
+		}
+
+		spin_unlock_irqrestore(lock, flags);
+
+		if (token)
+			handle_buf(token, len, vq, viortc_vq, viortc);
+	}
+}
+
+/**
+ * viortc_requestq_hdlr() - process a requestq used buffer
+ * @token: token identifying the buffer
+ * @len: bytes written by device
+ * @vq: virtqueue
+ * @viortc_vq: device specific data for virtqueue
+ * @viortc: device data
+ *
+ * Signals completion for each received message.
+ *
+ * Context: virtqueue callback
+ */
+static void viortc_requestq_hdlr(void *token, unsigned int len,
+				 struct virtqueue *vq,
+				 struct viortc_vq *viortc_vq,
+				 struct viortc_dev *viortc)
+{
+	struct viortc_msg *msg = token;
+
+	msg->resp_actual_size = len;
+
+	/*
+	 * completion waiter must see our msg metadata, but complete() does not
+	 * guarantee a memory barrier
+	 */
+	smp_wmb();
+
+	complete(&msg->responded);
+	viortc_msg_release(msg);
+}
+
+/**
+ * viortc_cb_requestq() - callback for requestq
+ * @vq: virtqueue
+ *
+ * Context: virtqueue callback
+ */
+static void viortc_cb_requestq(struct virtqueue *vq)
+{
+	viortc_do_cb(vq, viortc_requestq_hdlr);
+}
+
+/**
+ * viortc_get_resp_errno() - converts virtio_rtc errnos to system errnos
+ * @resp_head: message response header
+ *
+ * Return: negative system errno, or 0
+ */
+static int viortc_get_resp_errno(struct virtio_rtc_resp_head *resp_head)
+{
+	switch (virtio_le_to_cpu(resp_head->status)) {
+	case VIRTIO_RTC_S_OK:
+		return 0;
+	case VIRTIO_RTC_S_EOPNOTSUPP:
+		return -EOPNOTSUPP;
+	case VIRTIO_RTC_S_EINVAL:
+		return -EINVAL;
+	case VIRTIO_RTC_S_ENODEV:
+		return -ENODEV;
+	case VIRTIO_RTC_S_EIO:
+	default:
+		return -EIO;
+	}
+}
+
+/**
+ * viortc_msg_xfer() - send message request, wait until message response
+ * @vq: virtqueue
+ * @msg: message with driver request
+ * @timeout_jiffies: message response timeout, 0 for no timeout
+ *
+ * Context: Process context. Takes and releases vq.lock. May sleep.
+ */
+static int viortc_msg_xfer(struct viortc_vq *vq, struct viortc_msg *msg,
+			   unsigned long timeout_jiffies)
+{
+	int ret;
+	unsigned long flags;
+	struct scatterlist out_sg[1];
+	struct scatterlist in_sg[1];
+	struct scatterlist *sgs[2] = { out_sg, in_sg };
+	bool notify;
+
+	sg_init_one(out_sg, msg->req, msg->req_size);
+	sg_init_one(in_sg, msg->resp, msg->resp_cap);
+
+	spin_lock_irqsave(&vq->lock, flags);
+
+	ret = virtqueue_add_sgs(vq->vq, sgs, 1, 1, msg, GFP_ATOMIC);
+	if (ret) {
+		spin_unlock_irqrestore(&vq->lock, flags);
+		/*
+		 * Release in place of the response callback, which will never
+		 * come.
+		 */
+		viortc_msg_release(msg);
+		return ret;
+	}
+
+	notify = virtqueue_kick_prepare(vq->vq);
+
+	spin_unlock_irqrestore(&vq->lock, flags);
+
+	if (notify)
+		virtqueue_notify(vq->vq);
+
+	if (timeout_jiffies) {
+		long timeout_ret;
+
+		timeout_ret = wait_for_completion_interruptible_timeout(
+			&msg->responded, timeout_jiffies);
+
+		if (!timeout_ret)
+			return -ETIMEDOUT;
+		else if (timeout_ret < 0)
+			return (int)timeout_ret;
+	} else {
+		ret = wait_for_completion_interruptible(&msg->responded);
+		if (ret)
+			return ret;
+	}
+
+	/*
+	 * Ensure we can read message metadata written in the virtqueue
+	 * callback.
+	 */
+	smp_rmb();
+
+	/*
+	 * There is not yet a case where returning a short message would make
+	 * sense, so consider any deviation an error.
+	 */
+	if (msg->resp_actual_size != msg->resp_cap)
+		return -EINVAL;
+
+	return viortc_get_resp_errno(msg->resp);
+}
+
+/*
+ * common message handle macros for messages of different types
+ */
+
+/**
+ * VIORTC_DECLARE_MSG_HDL_ONSTACK() - declare message handle on stack
+ * @hdl: message handle name
+ * @msg_suf_lowerc: message type suffix in lowercase
+ * @msg_suf_upperc: message type suffix in uppercase
+ */
+#define VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, msg_suf_lowerc, msg_suf_upperc) \
+	struct {                                                            \
+		struct viortc_msg *msg;                                     \
+		struct virtio_rtc_req_##msg_suf_lowerc *req;                \
+		struct virtio_rtc_resp_##msg_suf_lowerc *resp;              \
+		unsigned int req_size;                                      \
+		unsigned int resp_cap;                                      \
+		u16 msg_type;                                               \
+	} hdl = {                                                           \
+		NULL,                                                       \
+		NULL,                                                       \
+		NULL,                                                       \
+		sizeof(struct virtio_rtc_req_##msg_suf_lowerc),             \
+		sizeof(struct virtio_rtc_resp_##msg_suf_lowerc),            \
+		VIRTIO_RTC_REQ_##msg_suf_upperc,                            \
+	}
+
+/**
+ * VIORTC_MSG() - extract message from message handle
+ *
+ * Return: struct viortc_msg
+ */
+#define VIORTC_MSG(hdl) ((hdl).msg)
+
+/**
+ * VIORTC_MSG_INIT() - initialize message handle
+ * @hdl: message handle
+ * @viortc: device data (struct viortc_dev *)
+ *
+ * Context: Process context.
+ * Return: 0 on success, -ENOMEM otherwise.
+ */
+#define VIORTC_MSG_INIT(hdl, viortc)                                         \
+	({                                                                   \
+		typeof(hdl) *_hdl = &(hdl);                                  \
+									     \
+		_hdl->msg = viortc_msg_init((viortc), _hdl->msg_type,        \
+					    _hdl->req_size, _hdl->resp_cap); \
+		if (_hdl->msg) {                                             \
+			_hdl->req = _hdl->msg->req;                          \
+			_hdl->resp = _hdl->msg->resp;                        \
+		}                                                            \
+		_hdl->msg ? 0 : -ENOMEM;                                     \
+	})
+
+/**
+ * VIORTC_MSG_WRITE() - write a request message field
+ * @hdl: message handle
+ * @dest_member: request message field name
+ * @src_ptr: pointer to data of compatible type
+ *
+ * Writes the field in little-endian format.
+ */
+#define VIORTC_MSG_WRITE(hdl, dest_member, src_ptr)                         \
+	do {                                                                \
+		typeof(hdl) _hdl = (hdl);                                   \
+		typeof(src_ptr) _src_ptr = (src_ptr);                       \
+									    \
+		/* Sanity check: must match the member's type */            \
+		typecheck(typeof(_hdl.req->dest_member), *_src_ptr);        \
+									    \
+		_hdl.req->dest_member =                                     \
+			virtio_cpu_to_le(*_src_ptr, _hdl.req->dest_member); \
+	} while (0)
+
+/**
+ * VIORTC_MSG_READ() - read from a response message field
+ * @hdl: message handle
+ * @src_member: response message field name
+ * @dest_ptr: pointer to data of compatible type
+ *
+ * Converts from little-endian format and writes to dest_ptr.
+ */
+#define VIORTC_MSG_READ(hdl, src_member, dest_ptr)                     \
+	do {                                                           \
+		typeof(dest_ptr) _dest_ptr = (dest_ptr);               \
+								       \
+		/* Sanity check: must match the member's type */       \
+		typecheck(typeof((hdl).resp->src_member), *_dest_ptr); \
+								       \
+		*_dest_ptr = virtio_le_to_cpu((hdl).resp->src_member); \
+	} while (0)
+
+/*
+ * read requests
+ */
+
+/** timeout for clock readings, where timeouts are considered non-fatal */
+#define VIORTC_MSG_READ_TIMEOUT (msecs_to_jiffies(60 * 1000))
+
+/**
+ * viortc_read() - VIRTIO_RTC_REQ_READ wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @reading: clock reading [ns]
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_read(struct viortc_dev *viortc, u16 vio_clk_id, u64 *reading)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, read, READ);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      VIORTC_MSG_READ_TIMEOUT);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, clock_reading, reading);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_read_cross() - VIRTIO_RTC_REQ_READ_CROSS wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @hw_counter: virtio_rtc HW counter type
+ * @reading: clock reading [ns]
+ * @cycles: HW counter cycles during clock reading
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_read_cross(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		      u64 *reading, u64 *cycles)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, read_cross, READ_CROSS);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+	VIORTC_MSG_WRITE(hdl, hw_counter, &hw_counter);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      VIORTC_MSG_READ_TIMEOUT);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, clock_reading, reading);
+	VIORTC_MSG_READ(hdl, counter_cycles, cycles);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/*
+ * control requests
+ */
+
+/**
+ * viortc_cfg() - VIRTIO_RTC_REQ_CFG wrapper
+ * @viortc: device data
+ * @num_clocks: # of virtio_rtc clocks
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_cfg(struct viortc_dev *viortc, u16 *num_clocks)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, cfg, CFG);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, num_clocks, num_clocks);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_clock_cap() - VIRTIO_RTC_REQ_CLOCK_CAP wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @type: virtio_rtc clock type
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_clock_cap(struct viortc_dev *viortc, u16 vio_clk_id,
+			    u16 *type)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, clock_cap, CLOCK_CAP);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, type, type);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_cross_cap() - VIRTIO_RTC_REQ_CROSS_CAP wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @hw_counter: virtio_rtc HW counter type
+ * @supported: xtstamping is supported for the vio_clk_id/hw_counter pair
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_cross_cap(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		     bool *supported)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, cross_cap, CROSS_CAP);
+	u8 flags;
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+	VIORTC_MSG_WRITE(hdl, hw_counter, &hw_counter);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, flags, &flags);
+	*supported = !!(flags & VIRTIO_RTC_FLAG_CROSS_CAP);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/*
+ * init, deinit
+ */
+
+/**
+ * viortc_clocks_init() - init local representations of virtio_rtc clocks
+ * @viortc: device data
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_clocks_init(struct viortc_dev *viortc)
+{
+	int ret;
+	u16 num_clocks;
+
+	ret = viortc_cfg(viortc, &num_clocks);
+	if (ret)
+		return ret;
+
+	if (num_clocks < 1) {
+		dev_err(&viortc->vdev->dev, "device reported 0 clocks\n");
+		return -ENODEV;
+	}
+
+	viortc->num_clocks = num_clocks;
+
+	/* In the future, PTP clocks will be initialized here. */
+	(void)viortc_clock_cap;
+
+	return ret;
+}
+
+/**
+ * viortc_init_vqs() - init virtqueues
+ * @viortc: device data
+ *
+ * Inits virtqueues and associated data.
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_init_vqs(struct viortc_dev *viortc)
+{
+	int ret;
+	struct virtio_device *vdev = viortc->vdev;
+	const char *names[VIORTC_MAX_NR_QUEUES];
+	vq_callback_t *callbacks[VIORTC_MAX_NR_QUEUES];
+	struct virtqueue *vqs[VIORTC_MAX_NR_QUEUES];
+	int nr_queues;
+
+	nr_queues = VIORTC_REQUESTQ + 1;
+	names[VIORTC_REQUESTQ] = "requestq";
+	callbacks[VIORTC_REQUESTQ] = viortc_cb_requestq;
+
+	ret = virtio_find_vqs(vdev, nr_queues, vqs, callbacks, names, NULL);
+	if (ret)
+		return ret;
+
+	viortc->vqs[VIORTC_REQUESTQ].vq = vqs[VIORTC_REQUESTQ];
+	spin_lock_init(&viortc->vqs[VIORTC_REQUESTQ].lock);
+
+	return 0;
+}
+
+/**
+ * viortc_probe() - probe a virtio_rtc virtio device
+ * @vdev: virtio device
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_probe(struct virtio_device *vdev)
+{
+	struct viortc_dev *viortc;
+	int ret;
+
+	viortc = devm_kzalloc(&vdev->dev, sizeof(*viortc), GFP_KERNEL);
+	if (!viortc)
+		return -ENOMEM;
+
+	vdev->priv = viortc;
+	viortc->vdev = vdev;
+
+	ret = viortc_init_vqs(viortc);
+	if (ret)
+		return ret;
+
+	virtio_device_ready(vdev);
+
+	/* Ready vdev for use by frontend devices initialized next. */
+	smp_wmb();
+
+	ret = viortc_clocks_init(viortc);
+	if (ret)
+		goto err_reset_vdev;
+
+	return 0;
+
+err_reset_vdev:
+	virtio_reset_device(vdev);
+	vdev->config->del_vqs(vdev);
+
+	return ret;
+}
+
+/**
+ * viortc_remove() - remove a virtio_rtc virtio device
+ * @vdev: virtio device
+ */
+static void viortc_remove(struct virtio_device *vdev)
+{
+	/* In the future, PTP clocks will be deinitialized here. */
+
+	virtio_reset_device(vdev);
+	vdev->config->del_vqs(vdev);
+}
+
+static struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_CLOCK, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+MODULE_DEVICE_TABLE(virtio, id_table);
+
+static struct virtio_driver virtio_rtc_drv = {
+	.driver.name = KBUILD_MODNAME,
+	.driver.owner = THIS_MODULE,
+	.id_table = id_table,
+	.probe = viortc_probe,
+	.remove = viortc_remove,
+};
+
+module_virtio_driver(virtio_rtc_drv);
+
+MODULE_DESCRIPTION("Virtio RTC driver");
+MODULE_AUTHOR("OpenSynergy GmbH");
+MODULE_LICENSE("GPL");
diff --git a/drivers/virtio/virtio_rtc_internal.h b/drivers/virtio/virtio_rtc_internal.h
new file mode 100644
index 000000000000..9267661b8030
--- /dev/null
+++ b/drivers/virtio/virtio_rtc_internal.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * virtio_rtc internal interfaces
+ *
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ */
+
+#ifndef _VIRTIO_RTC_INTERNAL_H_
+#define _VIRTIO_RTC_INTERNAL_H_
+
+#include <linux/types.h>
+
+/* driver core IFs */
+
+struct viortc_dev;
+
+int viortc_read(struct viortc_dev *viortc, u16 vio_clk_id, u64 *reading);
+int viortc_read_cross(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		      u64 *reading, u64 *cycles);
+int viortc_cross_cap(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		     bool *supported);
+
+#endif /* _VIRTIO_RTC_INTERNAL_H_ */
diff --git a/include/uapi/linux/virtio_rtc.h b/include/uapi/linux/virtio_rtc.h
new file mode 100644
index 000000000000..f469276562d7
--- /dev/null
+++ b/include/uapi/linux/virtio_rtc.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */
+/*
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ */
+
+#ifndef _LINUX_VIRTIO_RTC_H
+#define _LINUX_VIRTIO_RTC_H
+
+#include <linux/types.h>
+
+/* read request message types */
+
+#define VIRTIO_RTC_REQ_READ 0x0001
+#define VIRTIO_RTC_REQ_READ_CROSS 0x0002
+
+/* control request message types */
+
+#define VIRTIO_RTC_REQ_CFG 0x1000
+#define VIRTIO_RTC_REQ_CLOCK_CAP 0x1001
+#define VIRTIO_RTC_REQ_CROSS_CAP 0x1002
+
+/* Message headers */
+
+/** common request header */
+struct virtio_rtc_req_head {
+	__le16 msg_type;
+	__u8 reserved[6];
+};
+
+/** common response header */
+struct virtio_rtc_resp_head {
+#define VIRTIO_RTC_S_OK 0
+#define VIRTIO_RTC_S_EOPNOTSUPP 2
+#define VIRTIO_RTC_S_ENODEV 3
+#define VIRTIO_RTC_S_EINVAL 4
+#define VIRTIO_RTC_S_EIO 5
+	__u8 status;
+	__u8 reserved[7];
+};
+
+/* read requests */
+
+/* VIRTIO_RTC_REQ_READ message */
+
+struct virtio_rtc_req_read {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__u8 reserved[6];
+};
+
+struct virtio_rtc_resp_read {
+	struct virtio_rtc_resp_head head;
+	__le64 clock_reading;
+};
+
+/* VIRTIO_RTC_REQ_READ_CROSS message */
+
+struct virtio_rtc_req_read_cross {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+/** Arm Generic Timer Virtual Count */
+#define VIRTIO_RTC_COUNTER_ARM_VIRT 0
+/** Arm Generic Timer Physical Count */
+#define VIRTIO_RTC_COUNTER_ARM_PHYS 1
+/** x86 Time Stamp Counter */
+#define VIRTIO_RTC_COUNTER_X86_TSC 2
+	__le16 hw_counter;
+	__u8 reserved[4];
+};
+
+struct virtio_rtc_resp_read_cross {
+	struct virtio_rtc_resp_head head;
+	__le64 clock_reading;
+	__le64 counter_cycles;
+};
+
+/* control requests */
+
+/* VIRTIO_RTC_REQ_CFG message */
+
+struct virtio_rtc_req_cfg {
+	struct virtio_rtc_req_head head;
+	/* no request params */
+};
+
+struct virtio_rtc_resp_cfg {
+	struct virtio_rtc_resp_head head;
+	/** # of clocks -> clock ids < num_clocks are valid */
+	__le16 num_clocks;
+	__u8 reserved[6];
+};
+
+/* VIRTIO_RTC_REQ_CLOCK_CAP message */
+
+struct virtio_rtc_req_clock_cap {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__u8 reserved[6];
+};
+
+struct virtio_rtc_resp_clock_cap {
+	struct virtio_rtc_resp_head head;
+#define VIRTIO_RTC_CLOCK_UTC 0
+#define VIRTIO_RTC_CLOCK_TAI 1
+#define VIRTIO_RTC_CLOCK_MONO 2
+	__le16 type;
+	__u8 reserved[6];
+};
+
+/* VIRTIO_RTC_REQ_CROSS_CAP message */
+
+struct virtio_rtc_req_cross_cap {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__le16 hw_counter;
+	__u8 reserved[4];
+};
+
+struct virtio_rtc_resp_cross_cap {
+	struct virtio_rtc_resp_head head;
+#define VIRTIO_RTC_FLAG_CROSS_CAP (1 << 0)
+	__u8 flags;
+	__u8 reserved[7];
+};
+
+/** Union of request types for requestq */
+union virtio_rtc_req_requestq {
+	struct virtio_rtc_req_read read;
+	struct virtio_rtc_req_read_cross read_cross;
+	struct virtio_rtc_req_cfg cfg;
+	struct virtio_rtc_req_clock_cap clock_cap;
+	struct virtio_rtc_req_cross_cap cross_cap;
+};
+
+/** Union of response types for requestq */
+union virtio_rtc_resp_requestq {
+	struct virtio_rtc_resp_read read;
+	struct virtio_rtc_resp_read_cross read_cross;
+	struct virtio_rtc_resp_cfg cfg;
+	struct virtio_rtc_resp_clock_cap clock_cap;
+	struct virtio_rtc_resp_cross_cap cross_cap;
+};
+
+#endif /* _LINUX_VIRTIO_RTC_H */
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [RFC PATCH v3 4/7] virtio_rtc: Add module and driver core
@ 2023-12-18  7:38  5%   ` Peter Hilber
  0 siblings, 0 replies; 200+ results
From: Peter Hilber @ 2023-12-18  7:38 UTC (permalink / raw)
  To: linux-kernel, virtualization, virtio-dev
  Cc: Peter Hilber, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
	Richard Cochran, netdev, Marc Zyngier, Mark Rutland,
	Daniel Lezcano, Thomas Gleixner, linux-arm-kernel, linux-rtc,
	Alessandro Zummo, Alexandre Belloni

Add the virtio_rtc module and driver core. The virtio_rtc module implements
a driver compatible with the proposed Virtio RTC device specification.
The Virtio RTC (Real Time Clock) device provides information about current
time. The device can provide different clocks, e.g. for the UTC or TAI time
standards, or for physical time elapsed since some past epoch. The driver
can read the clocks with simple or more accurate methods.

Implement the core, which interacts with the Virtio RTC device. Apart from
this, the core does not expose functionality outside of the virtio_rtc
module. A follow-up patch will expose PTP clocks.

Provide synchronous messaging, which is enough for the expected time
synchronization use cases through PTP clocks (similar to ptp_kvm) or RTC
Class driver.

Signed-off-by: Peter Hilber <peter.hilber@opensynergy.com>
---

Notes:
    v3:
    
    - merge readq and controlq into a single requestq (spec v3)
    
    - don't guard cross-timestamping with feature bit (spec v3)
    
    - pad message headers to 64 bits (spec v3)
    
    - reduce clock id to 16 bits (spec v3)
    
    - change Virtio status codes (spec v3)
    
    - use 'VIRTIO_RTC_REQ_' prefix for request messages (spec v3)

 MAINTAINERS                          |   7 +
 drivers/virtio/Kconfig               |  13 +
 drivers/virtio/Makefile              |   2 +
 drivers/virtio/virtio_rtc_driver.c   | 761 +++++++++++++++++++++++++++
 drivers/virtio/virtio_rtc_internal.h |  23 +
 include/uapi/linux/virtio_rtc.h      | 144 +++++
 6 files changed, 950 insertions(+)
 create mode 100644 drivers/virtio/virtio_rtc_driver.c
 create mode 100644 drivers/virtio/virtio_rtc_internal.h
 create mode 100644 include/uapi/linux/virtio_rtc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index b589218605b4..0c157a19bbfd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23200,6 +23200,13 @@ S:	Maintained
 F:	drivers/nvdimm/nd_virtio.c
 F:	drivers/nvdimm/virtio_pmem.c
 
+VIRTIO RTC DRIVER
+M:	Peter Hilber <peter.hilber@opensynergy.com>
+L:	virtualization@lists.linux.dev
+S:	Maintained
+F:	drivers/virtio/virtio_rtc_*
+F:	include/uapi/linux/virtio_rtc.h
+
 VIRTIO SOUND DRIVER
 M:	Anton Yakovlev <anton.yakovlev@opensynergy.com>
 M:	"Michael S. Tsirkin" <mst@redhat.com>
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 0a53a61231c2..834dd14bc070 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -173,4 +173,17 @@ config VIRTIO_DMA_SHARED_BUFFER
 	 This option adds a flavor of dma buffers that are backed by
 	 virtio resources.
 
+config VIRTIO_RTC
+	tristate "Virtio RTC driver"
+	depends on VIRTIO
+	depends on PTP_1588_CLOCK_OPTIONAL
+	help
+	 This driver provides current time from a Virtio RTC device. The driver
+	 provides the time through one or more clocks.
+
+	 To compile this code as a module, choose M here: the module will be
+	 called virtio_rtc.
+
+	 If unsure, say M.
+
 endif # VIRTIO_MENU
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 8e98d24917cc..f760414ed6ab 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -12,3 +12,5 @@ obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o
 obj-$(CONFIG_VIRTIO_VDPA) += virtio_vdpa.o
 obj-$(CONFIG_VIRTIO_MEM) += virtio_mem.o
 obj-$(CONFIG_VIRTIO_DMA_SHARED_BUFFER) += virtio_dma_buf.o
+obj-$(CONFIG_VIRTIO_RTC) += virtio_rtc.o
+virtio_rtc-y := virtio_rtc_driver.o
diff --git a/drivers/virtio/virtio_rtc_driver.c b/drivers/virtio/virtio_rtc_driver.c
new file mode 100644
index 000000000000..ef1ea14b3bec
--- /dev/null
+++ b/drivers/virtio/virtio_rtc_driver.c
@@ -0,0 +1,761 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * virtio_rtc driver core
+ *
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ */
+
+#include <linux/completion.h>
+#include <linux/virtio.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+#include <linux/module.h>
+
+#include <uapi/linux/virtio_rtc.h>
+
+#include "virtio_rtc_internal.h"
+
+/* virtqueue order */
+enum {
+	VIORTC_REQUESTQ,
+	VIORTC_MAX_NR_QUEUES,
+};
+
+/**
+ * struct viortc_vq - virtqueue abstraction
+ * @vq: virtqueue
+ * @lock: protects access to vq
+ */
+struct viortc_vq {
+	struct virtqueue *vq;
+	spinlock_t lock;
+};
+
+/**
+ * struct viortc_dev - virtio_rtc device data
+ * @vdev: virtio device
+ * @vqs: virtqueues
+ * @num_clocks: # of virtio_rtc clocks
+ */
+struct viortc_dev {
+	struct virtio_device *vdev;
+	struct viortc_vq vqs[VIORTC_MAX_NR_QUEUES];
+	u16 num_clocks;
+};
+
+/**
+ * struct viortc_msg - Message requested by driver, responded by device.
+ * @viortc: device data
+ * @req: request buffer
+ * @resp: response buffer
+ * @responded: vqueue callback signals response reception
+ * @refcnt: Message reference count, message and buffers will be deallocated
+ *	    once 0. refcnt is decremented in the vqueue callback and in the
+ *	    thread waiting on the responded completion.
+ *          If a message response wait function times out, the message will be
+ *          freed upon late reception (refcnt will reach 0 in the callback), or
+ *          device removal.
+ * @req_size: size of request in bytes
+ * @resp_cap: maximum size of response in bytes
+ * @resp_actual_size: actual size of response
+ */
+struct viortc_msg {
+	struct viortc_dev *viortc;
+	void *req;
+	void *resp;
+	struct completion responded;
+	refcount_t refcnt;
+	unsigned int req_size;
+	unsigned int resp_cap;
+	unsigned int resp_actual_size;
+};
+
+/**
+ * viortc_msg_init() - Allocate and initialize requestq message.
+ * @viortc: device data
+ * @msg_type: virtio_rtc message type
+ * @req_size: size of request buffer to be allocated
+ * @resp_cap: size of response buffer to be allocated
+ *
+ * Initializes the message refcnt to 2. The refcnt will be decremented once in
+ * the virtqueue callback, and once in the thread waiting on the message (on
+ * completion or timeout).
+ *
+ * Context: Process context.
+ * Return: non-NULL on success.
+ */
+static struct viortc_msg *viortc_msg_init(struct viortc_dev *viortc,
+					  u16 msg_type, unsigned int req_size,
+					  unsigned int resp_cap)
+{
+	struct viortc_msg *msg;
+	struct device *dev = &viortc->vdev->dev;
+	struct virtio_rtc_req_head *req_head;
+
+	msg = devm_kzalloc(dev, sizeof(*msg), GFP_KERNEL);
+	if (!msg)
+		return NULL;
+
+	init_completion(&msg->responded);
+
+	msg->req = devm_kzalloc(dev, req_size, GFP_KERNEL);
+	if (!msg->req)
+		goto err_free_msg;
+
+	req_head = msg->req;
+
+	msg->resp = devm_kzalloc(dev, resp_cap, GFP_KERNEL);
+	if (!msg->resp)
+		goto err_free_msg_req;
+
+	msg->viortc = viortc;
+	msg->req_size = req_size;
+	msg->resp_cap = resp_cap;
+
+	refcount_set(&msg->refcnt, 2);
+
+	req_head->msg_type = virtio_cpu_to_le(msg_type, req_head->msg_type);
+
+	return msg;
+
+err_free_msg_req:
+	devm_kfree(dev, msg->req);
+
+err_free_msg:
+	devm_kfree(dev, msg);
+
+	return NULL;
+}
+
+/**
+ * viortc_msg_release() - Decrement message refcnt, potentially free message.
+ * @msg: message requested by driver
+ *
+ * Context: Any context.
+ */
+static void viortc_msg_release(struct viortc_msg *msg)
+{
+	if (refcount_dec_and_test(&msg->refcnt)) {
+		struct device *dev = &msg->viortc->vdev->dev;
+
+		devm_kfree(dev, msg->req);
+		devm_kfree(dev, msg->resp);
+		devm_kfree(dev, msg);
+	}
+}
+
+/**
+ * viortc_do_cb() - generic virtqueue callback logic
+ * @vq: virtqueue
+ * @handle_buf: function to process a used buffer
+ *
+ * Context: virtqueue callback, typically interrupt. Takes and releases vq lock.
+ */
+static void viortc_do_cb(struct virtqueue *vq,
+			 void (*handle_buf)(void *token, unsigned int len,
+					    struct virtqueue *vq,
+					    struct viortc_vq *viortc_vq,
+					    struct viortc_dev *viortc))
+{
+	struct viortc_dev *viortc = vq->vdev->priv;
+	struct viortc_vq *viortc_vq;
+	bool cb_enabled = true;
+	unsigned long flags;
+	spinlock_t *lock;
+	unsigned int len;
+	void *token;
+
+	viortc_vq = &viortc->vqs[vq->index];
+	lock = &viortc_vq->lock;
+
+	for (;;) {
+		spin_lock_irqsave(lock, flags);
+
+		if (cb_enabled) {
+			virtqueue_disable_cb(vq);
+			cb_enabled = false;
+		}
+
+		token = virtqueue_get_buf(vq, &len);
+		if (!token) {
+			if (virtqueue_enable_cb(vq)) {
+				spin_unlock_irqrestore(lock, flags);
+				return;
+			}
+			cb_enabled = true;
+		}
+
+		spin_unlock_irqrestore(lock, flags);
+
+		if (token)
+			handle_buf(token, len, vq, viortc_vq, viortc);
+	}
+}
+
+/**
+ * viortc_requestq_hdlr() - process a requestq used buffer
+ * @token: token identifying the buffer
+ * @len: bytes written by device
+ * @vq: virtqueue
+ * @viortc_vq: device specific data for virtqueue
+ * @viortc: device data
+ *
+ * Signals completion for each received message.
+ *
+ * Context: virtqueue callback
+ */
+static void viortc_requestq_hdlr(void *token, unsigned int len,
+				 struct virtqueue *vq,
+				 struct viortc_vq *viortc_vq,
+				 struct viortc_dev *viortc)
+{
+	struct viortc_msg *msg = token;
+
+	msg->resp_actual_size = len;
+
+	/*
+	 * completion waiter must see our msg metadata, but complete() does not
+	 * guarantee a memory barrier
+	 */
+	smp_wmb();
+
+	complete(&msg->responded);
+	viortc_msg_release(msg);
+}
+
+/**
+ * viortc_cb_requestq() - callback for requestq
+ * @vq: virtqueue
+ *
+ * Context: virtqueue callback
+ */
+static void viortc_cb_requestq(struct virtqueue *vq)
+{
+	viortc_do_cb(vq, viortc_requestq_hdlr);
+}
+
+/**
+ * viortc_get_resp_errno() - converts virtio_rtc errnos to system errnos
+ * @resp_head: message response header
+ *
+ * Return: negative system errno, or 0
+ */
+static int viortc_get_resp_errno(struct virtio_rtc_resp_head *resp_head)
+{
+	switch (virtio_le_to_cpu(resp_head->status)) {
+	case VIRTIO_RTC_S_OK:
+		return 0;
+	case VIRTIO_RTC_S_EOPNOTSUPP:
+		return -EOPNOTSUPP;
+	case VIRTIO_RTC_S_EINVAL:
+		return -EINVAL;
+	case VIRTIO_RTC_S_ENODEV:
+		return -ENODEV;
+	case VIRTIO_RTC_S_EIO:
+	default:
+		return -EIO;
+	}
+}
+
+/**
+ * viortc_msg_xfer() - send message request, wait until message response
+ * @vq: virtqueue
+ * @msg: message with driver request
+ * @timeout_jiffies: message response timeout, 0 for no timeout
+ *
+ * Context: Process context. Takes and releases vq.lock. May sleep.
+ */
+static int viortc_msg_xfer(struct viortc_vq *vq, struct viortc_msg *msg,
+			   unsigned long timeout_jiffies)
+{
+	int ret;
+	unsigned long flags;
+	struct scatterlist out_sg[1];
+	struct scatterlist in_sg[1];
+	struct scatterlist *sgs[2] = { out_sg, in_sg };
+	bool notify;
+
+	sg_init_one(out_sg, msg->req, msg->req_size);
+	sg_init_one(in_sg, msg->resp, msg->resp_cap);
+
+	spin_lock_irqsave(&vq->lock, flags);
+
+	ret = virtqueue_add_sgs(vq->vq, sgs, 1, 1, msg, GFP_ATOMIC);
+	if (ret) {
+		spin_unlock_irqrestore(&vq->lock, flags);
+		/*
+		 * Release in place of the response callback, which will never
+		 * come.
+		 */
+		viortc_msg_release(msg);
+		return ret;
+	}
+
+	notify = virtqueue_kick_prepare(vq->vq);
+
+	spin_unlock_irqrestore(&vq->lock, flags);
+
+	if (notify)
+		virtqueue_notify(vq->vq);
+
+	if (timeout_jiffies) {
+		long timeout_ret;
+
+		timeout_ret = wait_for_completion_interruptible_timeout(
+			&msg->responded, timeout_jiffies);
+
+		if (!timeout_ret)
+			return -ETIMEDOUT;
+		else if (timeout_ret < 0)
+			return (int)timeout_ret;
+	} else {
+		ret = wait_for_completion_interruptible(&msg->responded);
+		if (ret)
+			return ret;
+	}
+
+	/*
+	 * Ensure we can read message metadata written in the virtqueue
+	 * callback.
+	 */
+	smp_rmb();
+
+	/*
+	 * There is not yet a case where returning a short message would make
+	 * sense, so consider any deviation an error.
+	 */
+	if (msg->resp_actual_size != msg->resp_cap)
+		return -EINVAL;
+
+	return viortc_get_resp_errno(msg->resp);
+}
+
+/*
+ * common message handle macros for messages of different types
+ */
+
+/**
+ * VIORTC_DECLARE_MSG_HDL_ONSTACK() - declare message handle on stack
+ * @hdl: message handle name
+ * @msg_suf_lowerc: message type suffix in lowercase
+ * @msg_suf_upperc: message type suffix in uppercase
+ */
+#define VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, msg_suf_lowerc, msg_suf_upperc) \
+	struct {                                                            \
+		struct viortc_msg *msg;                                     \
+		struct virtio_rtc_req_##msg_suf_lowerc *req;                \
+		struct virtio_rtc_resp_##msg_suf_lowerc *resp;              \
+		unsigned int req_size;                                      \
+		unsigned int resp_cap;                                      \
+		u16 msg_type;                                               \
+	} hdl = {                                                           \
+		NULL,                                                       \
+		NULL,                                                       \
+		NULL,                                                       \
+		sizeof(struct virtio_rtc_req_##msg_suf_lowerc),             \
+		sizeof(struct virtio_rtc_resp_##msg_suf_lowerc),            \
+		VIRTIO_RTC_REQ_##msg_suf_upperc,                            \
+	}
+
+/**
+ * VIORTC_MSG() - extract message from message handle
+ *
+ * Return: struct viortc_msg
+ */
+#define VIORTC_MSG(hdl) ((hdl).msg)
+
+/**
+ * VIORTC_MSG_INIT() - initialize message handle
+ * @hdl: message handle
+ * @viortc: device data (struct viortc_dev *)
+ *
+ * Context: Process context.
+ * Return: 0 on success, -ENOMEM otherwise.
+ */
+#define VIORTC_MSG_INIT(hdl, viortc)                                         \
+	({                                                                   \
+		typeof(hdl) *_hdl = &(hdl);                                  \
+									     \
+		_hdl->msg = viortc_msg_init((viortc), _hdl->msg_type,        \
+					    _hdl->req_size, _hdl->resp_cap); \
+		if (_hdl->msg) {                                             \
+			_hdl->req = _hdl->msg->req;                          \
+			_hdl->resp = _hdl->msg->resp;                        \
+		}                                                            \
+		_hdl->msg ? 0 : -ENOMEM;                                     \
+	})
+
+/**
+ * VIORTC_MSG_WRITE() - write a request message field
+ * @hdl: message handle
+ * @dest_member: request message field name
+ * @src_ptr: pointer to data of compatible type
+ *
+ * Writes the field in little-endian format.
+ */
+#define VIORTC_MSG_WRITE(hdl, dest_member, src_ptr)                         \
+	do {                                                                \
+		typeof(hdl) _hdl = (hdl);                                   \
+		typeof(src_ptr) _src_ptr = (src_ptr);                       \
+									    \
+		/* Sanity check: must match the member's type */            \
+		typecheck(typeof(_hdl.req->dest_member), *_src_ptr);        \
+									    \
+		_hdl.req->dest_member =                                     \
+			virtio_cpu_to_le(*_src_ptr, _hdl.req->dest_member); \
+	} while (0)
+
+/**
+ * VIORTC_MSG_READ() - read from a response message field
+ * @hdl: message handle
+ * @src_member: response message field name
+ * @dest_ptr: pointer to data of compatible type
+ *
+ * Converts from little-endian format and writes to dest_ptr.
+ */
+#define VIORTC_MSG_READ(hdl, src_member, dest_ptr)                     \
+	do {                                                           \
+		typeof(dest_ptr) _dest_ptr = (dest_ptr);               \
+								       \
+		/* Sanity check: must match the member's type */       \
+		typecheck(typeof((hdl).resp->src_member), *_dest_ptr); \
+								       \
+		*_dest_ptr = virtio_le_to_cpu((hdl).resp->src_member); \
+	} while (0)
+
+/*
+ * read requests
+ */
+
+/** timeout for clock readings, where timeouts are considered non-fatal */
+#define VIORTC_MSG_READ_TIMEOUT (msecs_to_jiffies(60 * 1000))
+
+/**
+ * viortc_read() - VIRTIO_RTC_REQ_READ wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @reading: clock reading [ns]
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_read(struct viortc_dev *viortc, u16 vio_clk_id, u64 *reading)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, read, READ);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      VIORTC_MSG_READ_TIMEOUT);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, clock_reading, reading);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_read_cross() - VIRTIO_RTC_REQ_READ_CROSS wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @hw_counter: virtio_rtc HW counter type
+ * @reading: clock reading [ns]
+ * @cycles: HW counter cycles during clock reading
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_read_cross(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		      u64 *reading, u64 *cycles)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, read_cross, READ_CROSS);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+	VIORTC_MSG_WRITE(hdl, hw_counter, &hw_counter);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      VIORTC_MSG_READ_TIMEOUT);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, clock_reading, reading);
+	VIORTC_MSG_READ(hdl, counter_cycles, cycles);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/*
+ * control requests
+ */
+
+/**
+ * viortc_cfg() - VIRTIO_RTC_REQ_CFG wrapper
+ * @viortc: device data
+ * @num_clocks: # of virtio_rtc clocks
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_cfg(struct viortc_dev *viortc, u16 *num_clocks)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, cfg, CFG);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, num_clocks, num_clocks);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_clock_cap() - VIRTIO_RTC_REQ_CLOCK_CAP wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @type: virtio_rtc clock type
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_clock_cap(struct viortc_dev *viortc, u16 vio_clk_id,
+			    u16 *type)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, clock_cap, CLOCK_CAP);
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, type, type);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_cross_cap() - VIRTIO_RTC_REQ_CROSS_CAP wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @hw_counter: virtio_rtc HW counter type
+ * @supported: xtstamping is supported for the vio_clk_id/hw_counter pair
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_cross_cap(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		     bool *supported)
+{
+	int ret;
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, cross_cap, CROSS_CAP);
+	u8 flags;
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+	VIORTC_MSG_WRITE(hdl, hw_counter, &hw_counter);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, flags, &flags);
+	*supported = !!(flags & VIRTIO_RTC_FLAG_CROSS_CAP);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/*
+ * init, deinit
+ */
+
+/**
+ * viortc_clocks_init() - init local representations of virtio_rtc clocks
+ * @viortc: device data
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_clocks_init(struct viortc_dev *viortc)
+{
+	int ret;
+	u16 num_clocks;
+
+	ret = viortc_cfg(viortc, &num_clocks);
+	if (ret)
+		return ret;
+
+	if (num_clocks < 1) {
+		dev_err(&viortc->vdev->dev, "device reported 0 clocks\n");
+		return -ENODEV;
+	}
+
+	viortc->num_clocks = num_clocks;
+
+	/* In the future, PTP clocks will be initialized here. */
+	(void)viortc_clock_cap;
+
+	return ret;
+}
+
+/**
+ * viortc_init_vqs() - init virtqueues
+ * @viortc: device data
+ *
+ * Inits virtqueues and associated data.
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_init_vqs(struct viortc_dev *viortc)
+{
+	int ret;
+	struct virtio_device *vdev = viortc->vdev;
+	const char *names[VIORTC_MAX_NR_QUEUES];
+	vq_callback_t *callbacks[VIORTC_MAX_NR_QUEUES];
+	struct virtqueue *vqs[VIORTC_MAX_NR_QUEUES];
+	int nr_queues;
+
+	nr_queues = VIORTC_REQUESTQ + 1;
+	names[VIORTC_REQUESTQ] = "requestq";
+	callbacks[VIORTC_REQUESTQ] = viortc_cb_requestq;
+
+	ret = virtio_find_vqs(vdev, nr_queues, vqs, callbacks, names, NULL);
+	if (ret)
+		return ret;
+
+	viortc->vqs[VIORTC_REQUESTQ].vq = vqs[VIORTC_REQUESTQ];
+	spin_lock_init(&viortc->vqs[VIORTC_REQUESTQ].lock);
+
+	return 0;
+}
+
+/**
+ * viortc_probe() - probe a virtio_rtc virtio device
+ * @vdev: virtio device
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_probe(struct virtio_device *vdev)
+{
+	struct viortc_dev *viortc;
+	int ret;
+
+	viortc = devm_kzalloc(&vdev->dev, sizeof(*viortc), GFP_KERNEL);
+	if (!viortc)
+		return -ENOMEM;
+
+	vdev->priv = viortc;
+	viortc->vdev = vdev;
+
+	ret = viortc_init_vqs(viortc);
+	if (ret)
+		return ret;
+
+	virtio_device_ready(vdev);
+
+	/* Ready vdev for use by frontend devices initialized next. */
+	smp_wmb();
+
+	ret = viortc_clocks_init(viortc);
+	if (ret)
+		goto err_reset_vdev;
+
+	return 0;
+
+err_reset_vdev:
+	virtio_reset_device(vdev);
+	vdev->config->del_vqs(vdev);
+
+	return ret;
+}
+
+/**
+ * viortc_remove() - remove a virtio_rtc virtio device
+ * @vdev: virtio device
+ */
+static void viortc_remove(struct virtio_device *vdev)
+{
+	/* In the future, PTP clocks will be deinitialized here. */
+
+	virtio_reset_device(vdev);
+	vdev->config->del_vqs(vdev);
+}
+
+static struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_CLOCK, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+MODULE_DEVICE_TABLE(virtio, id_table);
+
+static struct virtio_driver virtio_rtc_drv = {
+	.driver.name = KBUILD_MODNAME,
+	.driver.owner = THIS_MODULE,
+	.id_table = id_table,
+	.probe = viortc_probe,
+	.remove = viortc_remove,
+};
+
+module_virtio_driver(virtio_rtc_drv);
+
+MODULE_DESCRIPTION("Virtio RTC driver");
+MODULE_AUTHOR("OpenSynergy GmbH");
+MODULE_LICENSE("GPL");
diff --git a/drivers/virtio/virtio_rtc_internal.h b/drivers/virtio/virtio_rtc_internal.h
new file mode 100644
index 000000000000..9267661b8030
--- /dev/null
+++ b/drivers/virtio/virtio_rtc_internal.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * virtio_rtc internal interfaces
+ *
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ */
+
+#ifndef _VIRTIO_RTC_INTERNAL_H_
+#define _VIRTIO_RTC_INTERNAL_H_
+
+#include <linux/types.h>
+
+/* driver core IFs */
+
+struct viortc_dev;
+
+int viortc_read(struct viortc_dev *viortc, u16 vio_clk_id, u64 *reading);
+int viortc_read_cross(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		      u64 *reading, u64 *cycles);
+int viortc_cross_cap(struct viortc_dev *viortc, u16 vio_clk_id, u16 hw_counter,
+		     bool *supported);
+
+#endif /* _VIRTIO_RTC_INTERNAL_H_ */
diff --git a/include/uapi/linux/virtio_rtc.h b/include/uapi/linux/virtio_rtc.h
new file mode 100644
index 000000000000..f469276562d7
--- /dev/null
+++ b/include/uapi/linux/virtio_rtc.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */
+/*
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ */
+
+#ifndef _LINUX_VIRTIO_RTC_H
+#define _LINUX_VIRTIO_RTC_H
+
+#include <linux/types.h>
+
+/* read request message types */
+
+#define VIRTIO_RTC_REQ_READ 0x0001
+#define VIRTIO_RTC_REQ_READ_CROSS 0x0002
+
+/* control request message types */
+
+#define VIRTIO_RTC_REQ_CFG 0x1000
+#define VIRTIO_RTC_REQ_CLOCK_CAP 0x1001
+#define VIRTIO_RTC_REQ_CROSS_CAP 0x1002
+
+/* Message headers */
+
+/** common request header */
+struct virtio_rtc_req_head {
+	__le16 msg_type;
+	__u8 reserved[6];
+};
+
+/** common response header */
+struct virtio_rtc_resp_head {
+#define VIRTIO_RTC_S_OK 0
+#define VIRTIO_RTC_S_EOPNOTSUPP 2
+#define VIRTIO_RTC_S_ENODEV 3
+#define VIRTIO_RTC_S_EINVAL 4
+#define VIRTIO_RTC_S_EIO 5
+	__u8 status;
+	__u8 reserved[7];
+};
+
+/* read requests */
+
+/* VIRTIO_RTC_REQ_READ message */
+
+struct virtio_rtc_req_read {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__u8 reserved[6];
+};
+
+struct virtio_rtc_resp_read {
+	struct virtio_rtc_resp_head head;
+	__le64 clock_reading;
+};
+
+/* VIRTIO_RTC_REQ_READ_CROSS message */
+
+struct virtio_rtc_req_read_cross {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+/** Arm Generic Timer Virtual Count */
+#define VIRTIO_RTC_COUNTER_ARM_VIRT 0
+/** Arm Generic Timer Physical Count */
+#define VIRTIO_RTC_COUNTER_ARM_PHYS 1
+/** x86 Time Stamp Counter */
+#define VIRTIO_RTC_COUNTER_X86_TSC 2
+	__le16 hw_counter;
+	__u8 reserved[4];
+};
+
+struct virtio_rtc_resp_read_cross {
+	struct virtio_rtc_resp_head head;
+	__le64 clock_reading;
+	__le64 counter_cycles;
+};
+
+/* control requests */
+
+/* VIRTIO_RTC_REQ_CFG message */
+
+struct virtio_rtc_req_cfg {
+	struct virtio_rtc_req_head head;
+	/* no request params */
+};
+
+struct virtio_rtc_resp_cfg {
+	struct virtio_rtc_resp_head head;
+	/** # of clocks -> clock ids < num_clocks are valid */
+	__le16 num_clocks;
+	__u8 reserved[6];
+};
+
+/* VIRTIO_RTC_REQ_CLOCK_CAP message */
+
+struct virtio_rtc_req_clock_cap {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__u8 reserved[6];
+};
+
+struct virtio_rtc_resp_clock_cap {
+	struct virtio_rtc_resp_head head;
+#define VIRTIO_RTC_CLOCK_UTC 0
+#define VIRTIO_RTC_CLOCK_TAI 1
+#define VIRTIO_RTC_CLOCK_MONO 2
+	__le16 type;
+	__u8 reserved[6];
+};
+
+/* VIRTIO_RTC_REQ_CROSS_CAP message */
+
+struct virtio_rtc_req_cross_cap {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__le16 hw_counter;
+	__u8 reserved[4];
+};
+
+struct virtio_rtc_resp_cross_cap {
+	struct virtio_rtc_resp_head head;
+#define VIRTIO_RTC_FLAG_CROSS_CAP (1 << 0)
+	__u8 flags;
+	__u8 reserved[7];
+};
+
+/** Union of request types for requestq */
+union virtio_rtc_req_requestq {
+	struct virtio_rtc_req_read read;
+	struct virtio_rtc_req_read_cross read_cross;
+	struct virtio_rtc_req_cfg cfg;
+	struct virtio_rtc_req_clock_cap clock_cap;
+	struct virtio_rtc_req_cross_cap cross_cap;
+};
+
+/** Union of response types for requestq */
+union virtio_rtc_resp_requestq {
+	struct virtio_rtc_resp_read read;
+	struct virtio_rtc_resp_read_cross read_cross;
+	struct virtio_rtc_resp_cfg cfg;
+	struct virtio_rtc_resp_clock_cap clock_cap;
+	struct virtio_rtc_resp_cross_cap cross_cap;
+};
+
+#endif /* _LINUX_VIRTIO_RTC_H */
-- 
2.40.1


^ permalink raw reply related	[relevance 5%]

* + mm-damon-dbgfs-implement-deprecation-notice-file.patch added to mm-unstable branch
@ 2024-01-30  6:44  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2024-01-30  6:44 UTC (permalink / raw)
  To: mm-commits, siyanteng, shuah, corbet, alexs, 2023002089, sj, akpm


The patch titled
     Subject: mm/damon/dbgfs: implement deprecation notice file
has been added to the -mm mm-unstable branch.  Its filename is
     mm-damon-dbgfs-implement-deprecation-notice-file.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-damon-dbgfs-implement-deprecation-notice-file.patch

This patch will later appear in the mm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: mm/damon/dbgfs: implement deprecation notice file
Date: Mon, 29 Jan 2024 17:35:42 -0800

Implement a read-only file for DAMON debugfs interface deprecation notice,
to let users who manually read/write the DAMON debugfs files from their
shell command line easily notice the fact.

Link: https://lkml.kernel.org/r/20240130013549.89538-4-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Alex Shi <alexs@kernel.org>
Cc: Hu Haowen <2023002089@link.tyut.edu.cn>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Yanteng Si <siyanteng@loongson.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 mm/damon/dbgfs.c |   20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

--- a/mm/damon/dbgfs.c~mm-damon-dbgfs-implement-deprecation-notice-file
+++ a/mm/damon/dbgfs.c
@@ -805,6 +805,18 @@ static void dbgfs_destroy_ctx(struct dam
 	damon_destroy_ctx(ctx);
 }
 
+static ssize_t damon_dbgfs_deprecated_read(struct file *file,
+		char __user *buf, size_t count, loff_t *ppos)
+{
+	char kbuf[512] = "DAMON debugfs interface is deprecated, "
+		     "so users should move to DAMON_SYSFS. If you cannot, "
+		     "please report your usecase to damon@lists.linux.dev and "
+		     "linux-mm@kvack.org.\n";
+	int len = strnlen(kbuf, 1024);
+
+	return simple_read_from_buffer(buf, count, ppos, kbuf, len);
+}
+
 /*
  * Make a context of @name and create a debugfs directory for it.
  *
@@ -1056,6 +1068,10 @@ static int damon_dbgfs_static_file_open(
 	return nonseekable_open(inode, file);
 }
 
+static const struct file_operations deprecated_fops = {
+	.read = damon_dbgfs_deprecated_read,
+};
+
 static const struct file_operations mk_contexts_fops = {
 	.open = damon_dbgfs_static_file_open,
 	.write = dbgfs_mk_context_write,
@@ -1076,9 +1092,9 @@ static int __init __damon_dbgfs_init(voi
 {
 	struct dentry *dbgfs_root;
 	const char * const file_names[] = {"mk_contexts", "rm_contexts",
-		"monitor_on"};
+		"monitor_on", "DEPRECATED"};
 	const struct file_operations *fops[] = {&mk_contexts_fops,
-		&rm_contexts_fops, &monitor_on_fops};
+		&rm_contexts_fops, &monitor_on_fops, &deprecated_fops};
 	int i;
 
 	dbgfs_root = debugfs_create_dir("damon", NULL);
_

Patches currently in -mm which might be from sj@kernel.org are

docs-admin-guide-mm-damon-usage-use-sysfs-interface-for-tracepoints-example.patch
mm-damon-rename-config_damon_dbgfs-to-damon_dbgfs_deprecated.patch
mm-damon-dbgfs-implement-deprecation-notice-file.patch
mm-damon-dbgfs-make-debugfs-interface-deprecation-message-a-macro.patch
docs-admin-guide-mm-damon-usage-document-deprecated-file-of-damon-debugfs-interface.patch
selftets-damon-prepare-for-monitor_on-file-renaming.patch
mm-damon-dbgfs-rename-monitor_on-file-to-monitor_on_deprecated.patch
docs-admin-guide-mm-damon-usage-update-for-monitor_on-renaming.patch
docs-translations-damon-usage-update-for-monitor_on-renaming.patch


^ permalink raw reply	[relevance 5%]

* [PATCH RFC 1/4] dt-bindings: input: touchscreen: Add Z2 controller bindings.
    2023-02-24 10:20  5%   ` Sasha Finkelstein via B4 Relay
@ 2023-02-24 10:20  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Relay @ 2023-02-24 10:20 UTC (permalink / raw)
  To: Hector Martin, Sven Peter, Alyssa Rosenzweig, Dmitry Torokhov,
	Rob Herring, Krzysztof Kozlowski, -, Henrik Rydberg
  Cc: linux-arm-kernel, linux-input, devicetree, linux-kernel,
	Sasha Finkelstein

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Add bindings for touchscreen controllers attached using the Z2 protocol.
Those are present in most Apple devices.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
---
 .../input/touchscreen/apple,z2-touchscreen.yaml    | 81 ++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/apple,z2-touchscreen.yaml b/Documentation/devicetree/bindings/input/touchscreen/apple,z2-touchscreen.yaml
new file mode 100644
index 000000000000..695594494b1e
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/apple,z2-touchscreen.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/apple,z2-touchscreen.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple touchscreens attached using the Z2 protocol.
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: A series of touschscreen controllers used in Apple products.
+
+allOf:
+  - $ref: touchscreen.yaml#
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+  compatible:
+    const: apple,z2-touchscreen
+
+  reg:
+    maxItems: 1
+
+  interrupts-extended:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+  cs-gpios:
+    maxItems: 1
+
+  firmware-name:
+    maxItems: 1
+
+  apple,z2-device-name:
+    description: The name to be used for the input device
+    $ref: /schemas/types.yaml#/definitions/string
+
+  touchscreen-size-x: true
+  touchscreen-size-y: true
+  spi-max-frequency: true
+
+required:
+  - compatible
+  - interrupts-extended
+  - reset-gpios
+  - cs-gpios
+  - firmware-name
+  - apple,z2-device-name
+  - touchscreen-size-x
+  - touchscreen-size-y
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            touchscreen@0 {
+                    compatible = "apple,z2-touchscreen";
+                    reg = <0>;
+                    spi-max-frequency = <11500000>;
+                    reset-gpios = <&pinctrl_ap 139 0>;
+                    cs-gpios = <&pinctrl_ap 109 0>;
+                    interrupts-extended = <&pinctrl_ap 194 IRQ_TYPE_EDGE_FALLING>;
+                    firmware-name = "apple/dfrmtfw-j293.bin";
+                    touchscreen-size-x = <23045>;
+                    touchscreen-size-y = <640>;
+                    apple,z2-device-name = "MacBookPro17,1 Touch Bar";
+            };
+    };
+
+...

-- 
Git-137.1)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v6 2/2] dt-bindings: soc: add loongson-2 chipid
  2022-11-04  2:48  5% [PATCH v6 1/2] soc: loongson: add GUTS driver for loongson-2 platforms Yinbo Zhu
@ 2022-11-04  2:48  5% ` Yinbo Zhu
  0 siblings, 0 replies; 200+ results
From: Yinbo Zhu @ 2022-11-04  2:48 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, soc, Yinbo Zhu
  Cc: Rob Herring

Add the Loongson-2 SoC chipid binding with DT schema format using
json-schema.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Change in v6:
		1. NO change, but other patch in this series of patches set	
		   has changes.
Change in v5:
		1. Add all history change log information.
		2. Add reviewed-by information.
Change in v4:
		1. NO change, but other patch in this series of patches set	
		   has changes.
Change in v3:
		1. Drop "driver" and describe instead what is GUTS, including
		   its acronym.
		2. Add desciption about the SoC register.
		3. Fixup dts node name.
		4. Replace string loongson2/Loongson2 with loongson-2/Loongson-2
                   in binding file and commit message.
Change in v2:
		1. NO change, but other patch in this series of patches set	
		   has changes.

 .../bindings/hwinfo/loongson,ls2k-chipid.yaml | 38 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 39 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml

diff --git a/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
new file mode 100644
index 000000000000..9d0c36ec1982
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwinfo/loongson,ls2k-chipid.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson-2 SoC ChipID
+
+maintainers:
+  - Yinbo Zhu <zhuyinbo@loongson.cn>
+
+description: |
+  Loongson-2 SoC contains many groups of global utilities register
+  blocks, of which the ChipID group registers record SoC version,
+  feature, vendor and id information.
+
+properties:
+  compatible:
+    const: loongson,ls2k-chipid
+
+  reg:
+    maxItems: 1
+
+  little-endian: true
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    chipid: chipid@1fe00000 {
+        compatible = "loongson,ls2k-chipid";
+        reg = <0x1fe00000 0x3ffc>;
+        little-endian;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 20ce056ae207..916b2d9cffc0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12045,6 +12045,7 @@ LOONGSON-2 SOC SERIES GUTS DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	loongarch@lists.linux.dev
 S:	Maintained
+F:	Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
 F:	drivers/soc/loongson/loongson2_guts.c
 
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
-- 
2.20.1


^ permalink raw reply related	[relevance 5%]

* [PATCH RFC 1/4] dt-bindings: input: touchscreen: Add Z2 controller bindings.
@ 2023-02-24 10:20  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Relay @ 2023-02-24 10:20 UTC (permalink / raw)
  To: Hector Martin, Sven Peter, Alyssa Rosenzweig, Dmitry Torokhov,
	Rob Herring, Krzysztof Kozlowski, -, Henrik Rydberg
  Cc: linux-arm-kernel, linux-input, devicetree, linux-kernel,
	Sasha Finkelstein

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Add bindings for touchscreen controllers attached using the Z2 protocol.
Those are present in most Apple devices.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
---
 .../input/touchscreen/apple,z2-touchscreen.yaml    | 81 ++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/apple,z2-touchscreen.yaml b/Documentation/devicetree/bindings/input/touchscreen/apple,z2-touchscreen.yaml
new file mode 100644
index 000000000000..695594494b1e
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/apple,z2-touchscreen.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/apple,z2-touchscreen.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple touchscreens attached using the Z2 protocol.
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: A series of touschscreen controllers used in Apple products.
+
+allOf:
+  - $ref: touchscreen.yaml#
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+  compatible:
+    const: apple,z2-touchscreen
+
+  reg:
+    maxItems: 1
+
+  interrupts-extended:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+  cs-gpios:
+    maxItems: 1
+
+  firmware-name:
+    maxItems: 1
+
+  apple,z2-device-name:
+    description: The name to be used for the input device
+    $ref: /schemas/types.yaml#/definitions/string
+
+  touchscreen-size-x: true
+  touchscreen-size-y: true
+  spi-max-frequency: true
+
+required:
+  - compatible
+  - interrupts-extended
+  - reset-gpios
+  - cs-gpios
+  - firmware-name
+  - apple,z2-device-name
+  - touchscreen-size-x
+  - touchscreen-size-y
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            touchscreen@0 {
+                    compatible = "apple,z2-touchscreen";
+                    reg = <0>;
+                    spi-max-frequency = <11500000>;
+                    reset-gpios = <&pinctrl_ap 139 0>;
+                    cs-gpios = <&pinctrl_ap 109 0>;
+                    interrupts-extended = <&pinctrl_ap 194 IRQ_TYPE_EDGE_FALLING>;
+                    firmware-name = "apple/dfrmtfw-j293.bin";
+                    touchscreen-size-x = <23045>;
+                    touchscreen-size-y = <640>;
+                    apple,z2-device-name = "MacBookPro17,1 Touch Bar";
+            };
+    };
+
+...

-- 
Git-137.1)


^ permalink raw reply related	[relevance 5%]

* add volatile flag to PV/LVs (for cache) to avoid degraded state on reboot
@ 2024-01-12 18:19  5% lists.linux.dev
  0 siblings, 0 replies; 200+ results
From: lists.linux.dev @ 2024-01-12 18:19 UTC (permalink / raw)
  To: linux-lvm

Hi,

at first, a happy new year to everyone.

I'm currently considering to use dm-cache with a ramdisk/volatile PV for a small project and noticed some usability issues that make using it less appealing.


Currently this means:
1. Adding a cache to a VG will cause the entire VG to depend on the cache. If one of the cache drives fails or is missing it cannot be accessed and even worse if this was the VG containing the root filesystem it also causes the entire system to fail to boot. Even though we may already know that we don't have any dataloss but just degraded access times.
2. Requires manual scripting to activate the VG and handle potentially missing/failing cache PVs
3. LVM doesn't have a way to clearly indicate that the physical volume is volatile and that dataloss on it is expected. Maybe even including the PV header itself. Or alternatively a way to indicate "if something is wrong with the cache, just forget about it (if possible)".
4. Just recreating the 'pvcreate --zero --pvmetadatacopies 0 --norestorefile --uuid' appears to be enough to get a write-through cache and thereby also the associated volume working again. Therefore it doesn't look like LVM cares about the cache data being lost, but only about the PV itself. Therefore failing to activate the VG appears to be a bit too convservative and probably the error handling here could be improved (see above).
6. Also as there is currently no place within the LVM metadata to label a PV/VG/LV as "volatile" it is also not clear both to LVM as well as admins looking at output of tools like lvdisplay that a specific LV is volatile. Therefore there will also be no safeguards and warnings against actions that would cause dataloss (like adding a ramdisk to a raid0, or even just adding a write-back instead of a write-through cache).


Therefore I'd like to ask if it would be possible to make two small improvements:
1. Add a "volatile" flag to PVs, LVs, and VGs to allow to clearly indicate that they are non-persistent and that dataloss is expected.
2. And one of:
 a. Change error handling and automatic recovery from missing PVs if the LV or VG has the volatile flag. Like e.g. automatically `--uncache`-ing the volume and mount it without the cache that is missing its PV. This is even more important for boot volumes, where such a configuration would prevent the system from booting at all.
 b. Alternatively, add native support for ramdisks. This mainly would require extending the VG metadata with an 'is-RAMdisk' flag that causes the lookup for the PV to be skipped and instead a new ramdisk being allocated while the VG is being activated (we know its size from the VG metadata, as we know how much we allocate/use). This could also help with unit tests and CI/CD usages (where currently the PV is manually created with brd before activating/creating the VG). Including our own test/lib/aux.sh, test/shell/devicesfile-misc.sh, test/shell/devicesfile-refresh.sh, test/shell/devicesfile-serial.sh.
 c. Same as 2a, but instead of automatically uncaching the volume, add a flag to the VG metadata that allows LVM to use the hints file to find the PV and automatically re-initialize it regardless of its header. Maybe together with an additional configuration option to demand the block device being zeroed (I.E. to avoid reading the entire block device, the first 4 sectors) to safeguard against accidental data-loss that we normally get by looking for the correct PV header.
 d. Same as 2b, but limited to caches only. Considering how caching is currently implemented adding ramdisks with an limitation to caches may cause unecessary additional work and be less useful compared to adding them as a new additional kind of PV. Also it wouldn't help the additional usecase with unit tests and CI/CD pipelines. Additionally it would also simplify "playing with" and learning about LVM.
 e. Add an option to have lvconvert enable caching but WITHOUT saving it within the VGs metadata. Causing LVM to forget about the case. I.E. next time the system boots LVM would mount the VG normally without the cache. For write-through caches this should always be safe and for write-back it only causes dataloss when the system crashes without flushing it.

My personal favourite is 2b, followed by 2e.
2b basically realizes my entire usecase within LVM natively and 2e at least avoids the need to automating the LVM recovery just to be able to reboot the system and allow me to write a systemd service to add the cache at runtime.

Best regards

^ permalink raw reply	[relevance 5%]

* + mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message.patch added to mm-unstable branch
@ 2023-02-09 22:14  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2023-02-09 22:14 UTC (permalink / raw)
  To: mm-commits, corbet, sj, akpm


The patch titled
     Subject: mm/damon/dbgfs: print DAMON debugfs interface deprecation message
has been added to the -mm mm-unstable branch.  Its filename is
     mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message.patch

This patch will later appear in the mm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: mm/damon/dbgfs: print DAMON debugfs interface deprecation message
Date: Thu, 9 Feb 2023 19:20:09 +0000

DAMON debugfs interface has announced to be deprecated after >v5.15 LTS
kernel is released.  And, v6.1.y has announced to be an LTS[1].

Though the announcement was there for a while, some people might not
noticed that so far.  Also, some users could depend on it and have
problems at  movng to the alternative (DAMON sysfs interface).

For such cases, warn DAMON debugfs interface deprecation with contacts
to ask helps when any DAMON debugfs interface file is opened.

[1] https://git.kernel.org/pub/scm/docs/kernel/website.git/commit/?id=332e9121320bc7461b2d3a79665caf153e51732c

Link: https://lkml.kernel.org/r/20230209192009.7885-4-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 mm/damon/dbgfs.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

--- a/mm/damon/dbgfs.c~mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message
+++ a/mm/damon/dbgfs.c
@@ -20,6 +20,11 @@ static int dbgfs_nr_ctxs;
 static struct dentry **dbgfs_dirs;
 static DEFINE_MUTEX(damon_dbgfs_lock);
 
+static void damon_dbgfs_warn_deprecation(void)
+{
+	pr_warn_once("DAMON debugfs interface is deprecated, so users should move to the sysfs interface (DAMON_SYSFS).  If you depend on this and cannot move, please report your usecase to damon@lists.linux.dev and linux-mm@kvack.org.\n");
+}
+
 /*
  * Returns non-empty string on success, negative error code otherwise.
  */
@@ -711,6 +716,8 @@ out:
 
 static int damon_dbgfs_open(struct inode *inode, struct file *file)
 {
+	damon_dbgfs_warn_deprecation();
+
 	file->private_data = inode->i_private;
 
 	return nonseekable_open(inode, file);
@@ -1039,15 +1046,24 @@ static ssize_t dbgfs_monitor_on_write(st
 	return ret;
 }
 
+static int damon_dbgfs_static_file_open(struct inode *inode, struct file *file)
+{
+	damon_dbgfs_warn_deprecation();
+	return nonseekable_open(inode, file);
+}
+
 static const struct file_operations mk_contexts_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.write = dbgfs_mk_context_write,
 };
 
 static const struct file_operations rm_contexts_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.write = dbgfs_rm_context_write,
 };
 
 static const struct file_operations monitor_on_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.read = dbgfs_monitor_on_read,
 	.write = dbgfs_monitor_on_write,
 };
_

Patches currently in -mm which might be from sj@kernel.org are

docs-admin-guide-mm-damon-usage-add-damon-debugfs-interface-deprecation-notice.patch
mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice.patch
mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message.patch


^ permalink raw reply	[relevance 5%]

* [PATCH v5 2/2] dt-bindings: soc: add loongson-2 chipid
  2022-11-03  8:19  6% [PATCH v5 1/2] soc: loongson: add GUTS driver for loongson-2 platforms Yinbo Zhu
@ 2022-11-03  8:19  5% ` Yinbo Zhu
  0 siblings, 0 replies; 200+ results
From: Yinbo Zhu @ 2022-11-03  8:19 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, Yinbo Zhu
  Cc: Rob Herring

Add the Loongson-2 SoC chipid binding with DT schema format using
json-schema.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Change in v5:
		1. Add all history change log information.
		2. Add reviewed-by information.
Change in v4:
		1. NO change, but other patch in this series of patches set	
		   has changes.
Change in v3:
		1. Drop "driver" and describe instead what is GUTS, including
		   its acronym.
		2. Add desciption about the SoC register.
		3. Fixup dts node name.
		4. Replace string loongson2/Loongson2 with loongson-2/Loongson-2
                   in binding file and commit message.
Change in v2:
		1. NO change, but other patch in this series of patches set	
		   has changes.

 .../bindings/hwinfo/loongson,ls2k-chipid.yaml | 38 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 39 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml

diff --git a/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
new file mode 100644
index 000000000000..9d0c36ec1982
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwinfo/loongson,ls2k-chipid.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson-2 SoC ChipID
+
+maintainers:
+  - Yinbo Zhu <zhuyinbo@loongson.cn>
+
+description: |
+  Loongson-2 SoC contains many groups of global utilities register
+  blocks, of which the ChipID group registers record SoC version,
+  feature, vendor and id information.
+
+properties:
+  compatible:
+    const: loongson,ls2k-chipid
+
+  reg:
+    maxItems: 1
+
+  little-endian: true
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    chipid: chipid@1fe00000 {
+        compatible = "loongson,ls2k-chipid";
+        reg = <0x1fe00000 0x3ffc>;
+        little-endian;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 20ce056ae207..916b2d9cffc0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12045,6 +12045,7 @@ LOONGSON-2 SOC SERIES GUTS DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	loongarch@lists.linux.dev
 S:	Maintained
+F:	Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
 F:	drivers/soc/loongson/loongson2_guts.c
 
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
-- 
2.20.1


^ permalink raw reply related	[relevance 5%]

* + mm-damon-rename-config_damon_dbgfs-to-damon_dbgfs_deprecated.patch added to mm-unstable branch
@ 2024-01-30  6:44  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2024-01-30  6:44 UTC (permalink / raw)
  To: mm-commits, siyanteng, shuah, corbet, alexs, 2023002089, sj, akpm


The patch titled
     Subject: mm/damon: rename CONFIG_DAMON_DBGFS to DAMON_DBGFS_DEPRECATED
has been added to the -mm mm-unstable branch.  Its filename is
     mm-damon-rename-config_damon_dbgfs-to-damon_dbgfs_deprecated.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-damon-rename-config_damon_dbgfs-to-damon_dbgfs_deprecated.patch

This patch will later appear in the mm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: mm/damon: rename CONFIG_DAMON_DBGFS to DAMON_DBGFS_DEPRECATED
Date: Mon, 29 Jan 2024 17:35:41 -0800

DAMON debugfs interface is deprecated.  The fact has documented by commit
5445fcbc4cda ("Docs/admin-guide/mm/damon/usage: add DAMON debugfs
interface deprecation notice").  Commit 620932cd2852 ("mm/damon/dbgfs:
print DAMON debugfs interface deprecation message") further started
printing a warning message when users still use it.  Many people don't
read documentation or kernel log, though.

Make the deprecation harder to be ignored using the approach of commit
eb07c4f39c3e ("mm/slab: rename CONFIG_SLAB to CONFIG_SLAB_DEPRECATED"). 
'make oldconfig' with 'CONFIG_DAMON_DBGFS=y' will get a new prompt with
the explicit deprecation notice on the name.  'make olddefconfig' with
'CONFIG_DAMON_DBGFS=y' will result in not building DAMON debugfs
interface.  If there is a real user of DAMON debugfs interface, they will
complain the change to the builder.

Link: https://lkml.kernel.org/r/20240130013549.89538-3-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Alex Shi <alexs@kernel.org>
Cc: Hu Haowen <2023002089@link.tyut.edu.cn>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Yanteng Si <siyanteng@loongson.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 mm/damon/Kconfig |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

--- a/mm/damon/Kconfig~mm-damon-rename-config_damon_dbgfs-to-damon_dbgfs_deprecated
+++ a/mm/damon/Kconfig
@@ -71,7 +71,7 @@ config DAMON_SYSFS_KUNIT_TEST
 
 	  If unsure, say N.
 
-config DAMON_DBGFS
+config DAMON_DBGFS_DEPRECATED
 	bool "DAMON debugfs interface (DEPRECATED!)"
 	depends on DAMON_VADDR && DAMON_PADDR && DEBUG_FS
 	help
@@ -84,6 +84,11 @@ config DAMON_DBGFS
 	  (DAMON_SYSFS).  If you depend on this and cannot move, please report
 	  your usecase to damon@lists.linux.dev and linux-mm@kvack.org.
 
+config DAMON_DBGFS
+	bool
+	default y
+	depends on DAMON_DBGFS_DEPRECATED
+
 config DAMON_DBGFS_KUNIT_TEST
 	bool "Test for damon debugfs interface" if !KUNIT_ALL_TESTS
 	depends on DAMON_DBGFS && KUNIT=y
_

Patches currently in -mm which might be from sj@kernel.org are

docs-admin-guide-mm-damon-usage-use-sysfs-interface-for-tracepoints-example.patch
mm-damon-rename-config_damon_dbgfs-to-damon_dbgfs_deprecated.patch
mm-damon-dbgfs-implement-deprecation-notice-file.patch
mm-damon-dbgfs-make-debugfs-interface-deprecation-message-a-macro.patch
docs-admin-guide-mm-damon-usage-document-deprecated-file-of-damon-debugfs-interface.patch
selftets-damon-prepare-for-monitor_on-file-renaming.patch
mm-damon-dbgfs-rename-monitor_on-file-to-monitor_on_deprecated.patch
docs-admin-guide-mm-damon-usage-update-for-monitor_on-renaming.patch
docs-translations-damon-usage-update-for-monitor_on-renaming.patch


^ permalink raw reply	[relevance 5%]

* [PATCH v2 3/4] ASoC: apple: mca: Start new platform driver
  @ 2022-08-19 12:54  5%   ` Martin Povišer
  0 siblings, 0 replies; 200+ results
From: Martin Povišer @ 2022-08-19 12:54 UTC (permalink / raw)
  To: Martin Povišer, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Hector Martin, Sven Peter, Philipp Zabel
  Cc: Alyssa Rosenzweig, asahi, alsa-devel, devicetree, linux-kernel

Add ASoC platform driver for the MCA peripheral found on Apple M1 and
other chips.

Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
---
 MAINTAINERS              |    8 +
 sound/soc/Kconfig        |    1 +
 sound/soc/Makefile       |    1 +
 sound/soc/apple/Kconfig  |    9 +
 sound/soc/apple/Makefile |    3 +
 sound/soc/apple/mca.c    | 1149 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 1171 insertions(+)
 create mode 100644 sound/soc/apple/Kconfig
 create mode 100644 sound/soc/apple/Makefile
 create mode 100644 sound/soc/apple/mca.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 8a5012ba6ff9..5f91a6b62f2f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1899,6 +1899,14 @@ F:	include/dt-bindings/pinctrl/apple.h
 F:	include/linux/apple-mailbox.h
 F:	include/linux/soc/apple/*
 
+ARM/APPLE MACHINE SOUND DRIVERS
+M:	Martin Povišer <povik+lin@cutebit.org>
+L:	asahi@lists.linux.dev
+L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/sound/apple,*
+F:	drivers/sound/apple/*
+
 ARM/ARTPEC MACHINE SUPPORT
 M:	Jesper Nilsson <jesper.nilsson@axis.com>
 M:	Lars Persson <lars.persson@axis.com>
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 7d4747b6bab2..848fbae26c3b 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -68,6 +68,7 @@ config SND_SOC_ACPI
 # All the supported SoCs
 source "sound/soc/adi/Kconfig"
 source "sound/soc/amd/Kconfig"
+source "sound/soc/apple/Kconfig"
 source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
 source "sound/soc/bcm/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 453181ef6c94..507eaed1d6a1 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SND_SOC_ACPI) += snd-soc-acpi.o
 obj-$(CONFIG_SND_SOC)	+= snd-soc-core.o
 obj-$(CONFIG_SND_SOC)	+= codecs/
 obj-$(CONFIG_SND_SOC)	+= generic/
+obj-$(CONFIG_SND_SOC)	+= apple/
 obj-$(CONFIG_SND_SOC)	+= adi/
 obj-$(CONFIG_SND_SOC)	+= amd/
 obj-$(CONFIG_SND_SOC)	+= atmel/
diff --git a/sound/soc/apple/Kconfig b/sound/soc/apple/Kconfig
new file mode 100644
index 000000000000..0ba955657e98
--- /dev/null
+++ b/sound/soc/apple/Kconfig
@@ -0,0 +1,9 @@
+config SND_SOC_APPLE_MCA
+	tristate "Apple Silicon MCA driver"
+	depends on ARCH_APPLE || COMPILE_TEST
+	select SND_DMAENGINE_PCM
+	select COMMON_CLK
+	default ARCH_APPLE
+	help
+	  This option enables an ASoC platform driver for MCA peripherals found
+	  on Apple Silicon SoCs.
diff --git a/sound/soc/apple/Makefile b/sound/soc/apple/Makefile
new file mode 100644
index 000000000000..7a30bf452817
--- /dev/null
+++ b/sound/soc/apple/Makefile
@@ -0,0 +1,3 @@
+snd-soc-apple-mca-objs	:= mca.o
+
+obj-$(CONFIG_SND_SOC_APPLE_MCA)	+= snd-soc-apple-mca.o
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
new file mode 100644
index 000000000000..6eeb35d49986
--- /dev/null
+++ b/sound/soc/apple/mca.c
@@ -0,0 +1,1149 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Apple SoCs MCA driver
+ *
+ * Copyright (C) The Asahi Linux Contributors
+ *
+ * The MCA peripheral is made up of a number of identical units called clusters.
+ * Each cluster has its separate clock parent, SYNC signal generator, carries
+ * four SERDES units and has a dedicated I2S port on the SoC's periphery.
+ *
+ * The clusters can operate independently, or can be combined together in a
+ * configurable manner. We mostly treat them as self-contained independent
+ * units and don't configure any cross-cluster connections except for the I2S
+ * ports. The I2S ports can be routed to any of the clusters (irrespective
+ * of their native cluster). We map this onto ASoC's (DPCM) notion of backend
+ * and frontend DAIs. The 'cluster guts' are frontends which are dynamically
+ * routed to backend I2S ports.
+ *
+ * DAI references in devicetree are resolved to backends. The routing between
+ * frontends and backends is determined by the machine driver in the DAPM paths
+ * it supplies.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_clk.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+
+#define USE_RXB_FOR_CAPTURE
+
+/* Relative to cluster base */
+#define REG_STATUS		0x0
+#define STATUS_MCLK_EN		BIT(0)
+#define REG_MCLK_CONF		0x4
+#define MCLK_CONF_DIV		GENMASK(11, 8)
+
+#define REG_SYNCGEN_STATUS	0x100
+#define SYNCGEN_STATUS_EN	BIT(0)
+#define REG_SYNCGEN_MCLK_SEL	0x104
+#define SYNCGEN_MCLK_SEL	GENMASK(3, 0)
+#define REG_SYNCGEN_HI_PERIOD	0x108
+#define REG_SYNCGEN_LO_PERIOD	0x10c
+
+#define REG_PORT_ENABLES	0x600
+#define PORT_ENABLES_CLOCKS	GENMASK(2, 1)
+#define PORT_ENABLES_TX_DATA	BIT(3)
+#define REG_PORT_CLOCK_SEL	0x604
+#define PORT_CLOCK_SEL		GENMASK(11, 8)
+#define REG_PORT_DATA_SEL	0x608
+#define PORT_DATA_SEL_TXA(cl)	(1 << ((cl)*2))
+#define PORT_DATA_SEL_TXB(cl)	(2 << ((cl)*2))
+
+#define REG_INTSTATE		0x700
+#define REG_INTMASK		0x704
+
+/* Bases of serdes units (relative to cluster) */
+#define CLUSTER_RXA_OFF	0x200
+#define CLUSTER_TXA_OFF	0x300
+#define CLUSTER_RXB_OFF	0x400
+#define CLUSTER_TXB_OFF	0x500
+
+#define CLUSTER_TX_OFF	CLUSTER_TXA_OFF
+
+#ifndef USE_RXB_FOR_CAPTURE
+#define CLUSTER_RX_OFF	CLUSTER_RXA_OFF
+#else
+#define CLUSTER_RX_OFF	CLUSTER_RXB_OFF
+#endif
+
+/* Relative to serdes unit base */
+#define REG_SERDES_STATUS	0x00
+#define SERDES_STATUS_EN	BIT(0)
+#define SERDES_STATUS_RST	BIT(1)
+#define REG_TX_SERDES_CONF	0x04
+#define REG_RX_SERDES_CONF	0x08
+#define SERDES_CONF_NCHANS	GENMASK(3, 0)
+#define SERDES_CONF_WIDTH_MASK	GENMASK(8, 4)
+#define SERDES_CONF_WIDTH_16BIT 0x40
+#define SERDES_CONF_WIDTH_20BIT 0x80
+#define SERDES_CONF_WIDTH_24BIT 0xc0
+#define SERDES_CONF_WIDTH_32BIT 0x100
+#define SERDES_CONF_BCLK_POL	0x400
+#define SERDES_CONF_LSB_FIRST	0x800
+#define SERDES_CONF_UNK1	BIT(12)
+#define SERDES_CONF_UNK2	BIT(13)
+#define SERDES_CONF_UNK3	BIT(14)
+#define SERDES_CONF_NO_DATA_FEEDBACK	BIT(15)
+#define SERDES_CONF_SYNC_SEL	GENMASK(18, 16)
+#define SERDES_CONF_SOME_RST	BIT(19)
+#define REG_TX_SERDES_BITSTART	0x08
+#define REG_RX_SERDES_BITSTART	0x0c
+#define REG_TX_SERDES_SLOTMASK	0x0c
+#define REG_RX_SERDES_SLOTMASK	0x10
+#define REG_RX_SERDES_PORT	0x04
+
+/* Relative to switch base */
+#define REG_DMA_ADAPTER_A(cl)	(0x8000 * (cl))
+#define REG_DMA_ADAPTER_B(cl)	(0x8000 * (cl) + 0x4000)
+#define DMA_ADAPTER_TX_LSB_PAD	GENMASK(4, 0)
+#define DMA_ADAPTER_TX_NCHANS	GENMASK(6, 5)
+#define DMA_ADAPTER_RX_MSB_PAD	GENMASK(12, 8)
+#define DMA_ADAPTER_RX_NCHANS	GENMASK(14, 13)
+#define DMA_ADAPTER_NCHANS	GENMASK(22, 20)
+
+#define SWITCH_STRIDE	0x8000
+#define CLUSTER_STRIDE	0x4000
+
+#define MAX_NCLUSTERS	6
+
+#define APPLE_MCA_FMTBITS (SNDRV_PCM_FMTBIT_S16_LE | \
+			   SNDRV_PCM_FMTBIT_S24_LE | \
+			   SNDRV_PCM_FMTBIT_S32_LE)
+
+struct mca_cluster {
+	int no;
+	__iomem void *base;
+	struct mca_data *host;
+	struct device *pd_dev;
+	struct clk *clk_parent;
+	struct dma_chan *dma_chans[SNDRV_PCM_STREAM_LAST + 1];
+
+	bool port_started[SNDRV_PCM_STREAM_LAST + 1];
+	int port_driver; /* The cluster driving this cluster's port */
+
+	bool clocks_in_use[SNDRV_PCM_STREAM_LAST + 1];
+	struct device_link *pd_link;
+
+	unsigned int bclk_ratio;
+
+	/* Masks etc. picked up via the set_tdm_slot method */
+	int tdm_slots;
+	int tdm_slot_width;
+	unsigned int tdm_tx_mask;
+	unsigned int tdm_rx_mask;
+};
+
+struct mca_data {
+	struct device *dev;
+
+	__iomem void *switch_base;
+
+	struct device *pd_dev;
+	struct reset_control *rstc;
+	struct device_link *pd_link;
+
+	int nclusters;
+	struct mca_cluster clusters[];
+};
+
+static void mca_modify(struct mca_cluster *cl, int regoffset, u32 mask, u32 val)
+{
+	__iomem void *ptr = cl->base + regoffset;
+	u32 newval;
+
+	newval = (val & mask) | (readl_relaxed(ptr) & ~mask);
+	writel_relaxed(newval, ptr);
+}
+
+/*
+ * Get the cluster of FE or BE DAI
+ */
+static struct mca_cluster *mca_dai_to_cluster(struct snd_soc_dai *dai)
+{
+	struct mca_data *mca = snd_soc_dai_get_drvdata(dai);
+	/*
+	 * FE DAIs are         0 ... nclusters - 1
+	 * BE DAIs are nclusters ... 2*nclusters - 1
+	 */
+	int cluster_no = dai->id % mca->nclusters;
+
+	return &mca->clusters[cluster_no];
+}
+
+/* called before PCM trigger */
+static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
+				 struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+	int serdes_conf =
+		serdes_unit + (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_RST);
+		mca_modify(cl, serdes_conf, SERDES_CONF_SOME_RST,
+			   SERDES_CONF_SOME_RST);
+		readl_relaxed(cl->base + serdes_conf);
+		mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
+		WARN_ON(readl_relaxed(cl->base + REG_SERDES_STATUS) &
+			SERDES_STATUS_RST);
+		break;
+	default:
+		break;
+	}
+}
+
+static int mca_fe_trigger(struct snd_pcm_substream *substream, int cmd,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_EN);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mca_fe_enable_clocks(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	int ret;
+
+	ret = clk_prepare_enable(cl->clk_parent);
+	if (ret) {
+		dev_err(mca->dev,
+			"cluster %d: unable to enable clock parent: %d\n",
+			cl->no, ret);
+		return ret;
+	}
+
+	/*
+	 * We can't power up the device earlier than this because
+	 * the power state driver would error out on seeing the device
+	 * as clock-gated.
+	 */
+	cl->pd_link = device_link_add(mca->dev, cl->pd_dev,
+				      DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					      DL_FLAG_RPM_ACTIVE);
+	if (!cl->pd_link) {
+		dev_err(mca->dev,
+			"cluster %d: unable to prop-up power domain\n", cl->no);
+		clk_disable_unprepare(cl->clk_parent);
+		return -EINVAL;
+	}
+
+	writel_relaxed(cl->no + 1, cl->base + REG_SYNCGEN_MCLK_SEL);
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN,
+		   SYNCGEN_STATUS_EN);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, STATUS_MCLK_EN);
+
+	return 0;
+}
+
+static void mca_fe_disable_clocks(struct mca_cluster *cl)
+{
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN, 0);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, 0);
+
+	device_link_del(cl->pd_link);
+	clk_disable_unprepare(cl->clk_parent);
+}
+
+static bool mca_fe_clocks_in_use(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *be_cl;
+	int stream, i;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		be_cl = &mca->clusters[i];
+
+		if (be_cl->port_driver != cl->no)
+			continue;
+
+		for_each_pcm_streams(stream)
+			if (be_cl->clocks_in_use[stream])
+				return true;
+	}
+	return false;
+}
+
+static int mca_be_prepare(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+	int ret;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+
+	/*
+	 * Typically the CODECs we are paired with will require clocks
+	 * to be present at time of unmute with the 'mute_stream' op
+	 * or at time of DAPM widget power-up. We need to enable clocks
+	 * here at the latest (frontend prepare would be too late).
+	 */
+	if (!mca_fe_clocks_in_use(fe_cl)) {
+		ret = mca_fe_enable_clocks(fe_cl);
+		if (ret < 0)
+			return ret;
+	}
+
+	cl->clocks_in_use[substream->stream] = true;
+
+	return 0;
+}
+
+static int mca_be_hw_free(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+	if (!mca_fe_clocks_in_use(fe_cl))
+		return 0; /* Nothing to do */
+
+	cl->clocks_in_use[substream->stream] = false;
+
+	if (!mca_fe_clocks_in_use(fe_cl))
+		mca_fe_disable_clocks(fe_cl);
+
+	return 0;
+}
+
+static unsigned int mca_crop_mask(unsigned int mask, int nchans)
+{
+	while (hweight32(mask) > nchans)
+		mask &= ~(1 << __fls(mask));
+
+	return mask;
+}
+
+static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
+				unsigned int mask, int slots, int nchans,
+				int slot_width, bool is_tx, int port)
+{
+	__iomem void *serdes_base = cl->base + serdes_unit;
+	u32 serdes_conf, serdes_conf_mask;
+
+	serdes_conf_mask = SERDES_CONF_WIDTH_MASK | SERDES_CONF_NCHANS;
+	serdes_conf = FIELD_PREP(SERDES_CONF_NCHANS, max(slots, 1) - 1);
+	switch (slot_width) {
+	case 16:
+		serdes_conf |= SERDES_CONF_WIDTH_16BIT;
+		break;
+	case 20:
+		serdes_conf |= SERDES_CONF_WIDTH_20BIT;
+		break;
+	case 24:
+		serdes_conf |= SERDES_CONF_WIDTH_24BIT;
+		break;
+	case 32:
+		serdes_conf |= SERDES_CONF_WIDTH_32BIT;
+		break;
+	default:
+		goto err;
+	}
+
+	serdes_conf_mask |= SERDES_CONF_SYNC_SEL;
+	serdes_conf |= FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1);
+
+	if (is_tx) {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_UNK3;
+	} else {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3 |
+				    SERDES_CONF_NO_DATA_FEEDBACK;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_NO_DATA_FEEDBACK;
+	}
+
+	mca_modify(cl,
+		   serdes_unit +
+			   (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF),
+		   serdes_conf_mask, serdes_conf);
+
+	if (is_tx) {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x8);
+		writel_relaxed(~((u32)mask),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0xc);
+	} else {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_RX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_RX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(1 << port,
+			       serdes_base + REG_RX_SERDES_PORT);
+	}
+
+	return 0;
+
+err:
+	dev_err(cl->host->dev,
+		"unsupported SERDES configuration requested (mask=0x%x slots=%d slot_width=%d)\n",
+		mask, slots, slot_width);
+	return -EINVAL;
+}
+
+static int mca_fe_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+			       unsigned int rx_mask, int slots, int slot_width)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->tdm_slots = slots;
+	cl->tdm_slot_width = slot_width;
+	cl->tdm_tx_mask = tx_mask;
+	cl->tdm_rx_mask = rx_mask;
+
+	return 0;
+}
+
+static int mca_fe_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	bool fpol_inv = false;
+	u32 serdes_conf = 0;
+	u32 bitstart;
+
+	if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) !=
+	    SND_SOC_DAIFMT_BP_FP)
+		goto err;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		fpol_inv = 0;
+		bitstart = 1;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		fpol_inv = 1;
+		bitstart = 0;
+		break;
+	default:
+		goto err;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_IF:
+	case SND_SOC_DAIFMT_IB_IF:
+		fpol_inv ^= 1;
+		break;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+	case SND_SOC_DAIFMT_NB_IF:
+		serdes_conf |= SERDES_CONF_BCLK_POL;
+		break;
+	}
+
+	if (!fpol_inv)
+		goto err;
+
+	mca_modify(cl, CLUSTER_TX_OFF + REG_TX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	mca_modify(cl, CLUSTER_RX_OFF + REG_RX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_TX_OFF + REG_TX_SERDES_BITSTART);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_RX_OFF + REG_RX_SERDES_BITSTART);
+
+	return 0;
+
+err:
+	dev_err(mca->dev, "unsupported DAI format (0x%x) requested\n", fmt);
+	return -EINVAL;
+}
+
+static int mca_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->bclk_ratio = ratio;
+
+	return 0;
+}
+
+static int mca_fe_get_port(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *be;
+	struct snd_soc_dpcm *dpcm;
+
+	be = NULL;
+	for_each_dpcm_be(fe, substream->stream, dpcm) {
+		be = dpcm->be;
+		break;
+	}
+
+	if (!be)
+		return -EINVAL;
+
+	return mca_dai_to_cluster(asoc_rtd_to_cpu(be, 0))->no;
+}
+
+static int mca_fe_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct device *dev = mca->dev;
+	unsigned int samp_rate = params_rate(params);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	bool refine_tdm = false;
+	unsigned long bclk_ratio;
+	unsigned int tdm_slots, tdm_slot_width, tdm_mask;
+	u32 regval, pad;
+	int ret, port, nchans_ceiled;
+
+	if (!cl->tdm_slot_width) {
+		/*
+		 * We were not given TDM settings from above, set initial
+		 * guesses which will later be refined.
+		 */
+		tdm_slot_width = params_width(params);
+		tdm_slots = params_channels(params);
+		refine_tdm = true;
+	} else {
+		tdm_slot_width = cl->tdm_slot_width;
+		tdm_slots = cl->tdm_slots;
+		tdm_mask = is_tx ? cl->tdm_tx_mask : cl->tdm_rx_mask;
+	}
+
+	if (cl->bclk_ratio)
+		bclk_ratio = cl->bclk_ratio;
+	else
+		bclk_ratio = tdm_slot_width * tdm_slots;
+
+	if (refine_tdm) {
+		int nchannels = params_channels(params);
+
+		if (nchannels > 2) {
+			dev_err(dev, "missing TDM for stream with two or more channels\n");
+			return -EINVAL;
+		}
+
+		if ((bclk_ratio % nchannels) != 0) {
+			dev_err(dev, "BCLK ratio (%ld) not divisible by no. of channels (%d)\n",
+				bclk_ratio, nchannels);
+			return -EINVAL;
+		}
+
+		tdm_slot_width = bclk_ratio / nchannels;
+
+		if (tdm_slot_width > 32 && nchannels == 1)
+			tdm_slot_width = 32;
+
+		if (tdm_slot_width < params_width(params)) {
+			dev_err(dev, "TDM slots too narrow (tdm=%d params=%d)\n",
+				tdm_slot_width, params_width(params));
+			return -EINVAL;
+		}
+
+		tdm_mask = (1 << tdm_slots) - 1;
+	}
+
+	port = mca_fe_get_port(substream);
+	if (port < 0)
+		return port;
+
+	ret = mca_configure_serdes(cl, is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF,
+				   tdm_mask, tdm_slots, params_channels(params),
+				   tdm_slot_width, is_tx, port);
+	if (ret)
+		return ret;
+
+	pad = 32 - params_width(params);
+
+	/*
+	 * TODO: Here the register semantics aren't clear.
+	 */
+	nchans_ceiled = min_t(int, params_channels(params), 4);
+	regval = FIELD_PREP(DMA_ADAPTER_NCHANS, nchans_ceiled) |
+		 FIELD_PREP(DMA_ADAPTER_TX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_RX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_TX_LSB_PAD, pad) |
+		 FIELD_PREP(DMA_ADAPTER_RX_MSB_PAD, pad);
+
+#ifndef USE_RXB_FOR_CAPTURE
+	writel_relaxed(regval, mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+#else
+	if (is_tx)
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+	else
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_B(cl->no));
+#endif
+
+	if (!mca_fe_clocks_in_use(cl)) {
+		/*
+		 * Set up FSYNC duty cycle as even as possible.
+		 */
+		writel_relaxed((bclk_ratio / 2) - 1,
+			       cl->base + REG_SYNCGEN_HI_PERIOD);
+		writel_relaxed(((bclk_ratio + 1) / 2) - 1,
+			       cl->base + REG_SYNCGEN_LO_PERIOD);
+		writel_relaxed(FIELD_PREP(MCLK_CONF_DIV, 0x1),
+			       cl->base + REG_MCLK_CONF);
+
+		ret = clk_set_rate(cl->clk_parent, bclk_ratio * samp_rate);
+		if (ret) {
+			dev_err(mca->dev, "cluster %d: unable to set clock parent: %d\n",
+				cl->no, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops mca_fe_ops = {
+	.set_fmt = mca_fe_set_fmt,
+	.set_bclk_ratio = mca_set_bclk_ratio,
+	.set_tdm_slot = mca_fe_set_tdm_slot,
+	.hw_params = mca_fe_hw_params,
+	.trigger = mca_fe_trigger,
+};
+
+static bool mca_be_started(struct mca_cluster *cl)
+{
+	int stream;
+
+	for_each_pcm_streams(stream)
+		if (cl->port_started[stream])
+			return true;
+	return false;
+}
+
+static int mca_be_startup(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *be = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *fe;
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_cluster *fe_cl;
+	struct mca_data *mca = cl->host;
+	struct snd_soc_dpcm *dpcm;
+
+	fe = NULL;
+
+	for_each_dpcm_fe(be, substream->stream, dpcm) {
+		if (fe && dpcm->fe != fe) {
+			dev_err(mca->dev, "many FE per one BE unsupported\n");
+			return -EINVAL;
+		}
+
+		fe = dpcm->fe;
+	}
+
+	if (!fe)
+		return -EINVAL;
+
+	fe_cl = mca_dai_to_cluster(asoc_rtd_to_cpu(fe, 0));
+
+	if (mca_be_started(cl)) {
+		/*
+		 * Port is already started in the other direction.
+		 * Make sure there isn't a conflict with another cluster
+		 * driving the port.
+		 */
+		if (cl->port_driver != fe_cl->no)
+			return -EINVAL;
+
+		cl->port_started[substream->stream] = true;
+		return 0;
+	}
+
+	writel_relaxed(PORT_ENABLES_CLOCKS | PORT_ENABLES_TX_DATA,
+		       cl->base + REG_PORT_ENABLES);
+	writel_relaxed(FIELD_PREP(PORT_CLOCK_SEL, fe_cl->no + 1),
+		       cl->base + REG_PORT_CLOCK_SEL);
+	writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no),
+		       cl->base + REG_PORT_DATA_SEL);
+	cl->port_driver = fe_cl->no;
+	cl->port_started[substream->stream] = true;
+
+	return 0;
+}
+
+static void mca_be_shutdown(struct snd_pcm_substream *substream,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->port_started[substream->stream] = false;
+
+	if (!mca_be_started(cl)) {
+		/*
+		 * Were we the last direction to shutdown?
+		 * Turn off the lights.
+		 */
+		writel_relaxed(0, cl->base + REG_PORT_ENABLES);
+		writel_relaxed(0, cl->base + REG_PORT_DATA_SEL);
+		cl->port_driver = -1;
+	}
+}
+
+static const struct snd_soc_dai_ops mca_be_ops = {
+	.prepare = mca_be_prepare,
+	.hw_free = mca_be_hw_free,
+	.startup = mca_be_startup,
+	.shutdown = mca_be_shutdown,
+};
+
+static int mca_set_runtime_hwparams(struct snd_soc_component *component,
+				    struct snd_pcm_substream *substream,
+				    struct dma_chan *chan)
+{
+	struct device *dma_dev = chan->device->dev;
+	struct snd_dmaengine_dai_dma_data dma_data = {};
+	int ret;
+
+	struct snd_pcm_hardware hw;
+
+	memset(&hw, 0, sizeof(hw));
+
+	hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+		  SNDRV_PCM_INFO_INTERLEAVED;
+	hw.periods_min = 2;
+	hw.periods_max = UINT_MAX;
+	hw.period_bytes_min = 256;
+	hw.period_bytes_max = dma_get_max_seg_size(dma_dev);
+	hw.buffer_bytes_max = SIZE_MAX;
+	hw.fifo_size = 16;
+
+	ret = snd_dmaengine_pcm_refine_runtime_hwparams(substream, &dma_data,
+							&hw, chan);
+
+	if (ret)
+		return ret;
+
+	return snd_soc_set_runtime_hwparams(substream, &hw);
+}
+
+static int mca_pcm_open(struct snd_soc_component *component,
+			struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	struct dma_chan *chan = cl->dma_chans[substream->stream];
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	ret = mca_set_runtime_hwparams(component, substream, chan);
+	if (ret)
+		return ret;
+
+	return snd_dmaengine_pcm_open(substream, chan);
+}
+
+static int mca_hw_params(struct snd_soc_component *component,
+			 struct snd_pcm_substream *substream,
+			 struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
+	struct dma_slave_config slave_config;
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	memset(&slave_config, 0, sizeof(slave_config));
+	ret = snd_hwparams_to_dma_slave_config(substream, params,
+					       &slave_config);
+	if (ret < 0)
+		return ret;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		slave_config.dst_port_window_size =
+			min_t(u32, params_channels(params), 4);
+	else
+		slave_config.src_port_window_size =
+			min_t(u32, params_channels(params), 4);
+
+	return dmaengine_slave_config(chan, &slave_config);
+}
+
+static int mca_close(struct snd_soc_component *component,
+		     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	return snd_dmaengine_pcm_close(substream);
+}
+
+static int mca_trigger(struct snd_soc_component *component,
+		       struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	/*
+	 * Before we do the PCM trigger proper, insert an opportunity
+	 * to reset the frontend's SERDES.
+	 */
+	mca_fe_early_trigger(substream, cmd, asoc_rtd_to_cpu(rtd, 0));
+
+	return snd_dmaengine_pcm_trigger(substream, cmd);
+}
+
+static snd_pcm_uframes_t mca_pointer(struct snd_soc_component *component,
+				     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return -ENOTSUPP;
+
+	return snd_dmaengine_pcm_pointer(substream);
+}
+
+static int mca_pcm_new(struct snd_soc_component *component,
+		       struct snd_soc_pcm_runtime *rtd)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	unsigned int i;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	for_each_pcm_streams(i) {
+		struct snd_pcm_substream *substream =
+			rtd->pcm->streams[i].substream;
+		struct dma_chan *chan = cl->dma_chans[i];
+
+		if (!substream)
+			continue;
+
+		if (!chan) {
+			dev_err(component->dev, "missing DMA channel for stream %d on SERDES %d\n",
+				i, cl->no);
+			return -EINVAL;
+		}
+
+		snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV_IRAM,
+					   chan->device->dev, 512 * 1024 * 6,
+					   SIZE_MAX);
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_component_driver mca_component = {
+	.name = "apple-mca",
+	.open = mca_pcm_open,
+	.close = mca_close,
+	.hw_params = mca_hw_params,
+	.trigger = mca_trigger,
+	.pointer = mca_pointer,
+	.pcm_construct = mca_pcm_new,
+};
+
+static void apple_mca_release(struct mca_data *mca)
+{
+	int i, stream;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		struct mca_cluster *cl = &mca->clusters[i];
+
+		for_each_pcm_streams(stream) {
+			if (IS_ERR_OR_NULL(cl->dma_chans[stream]))
+				continue;
+
+			dma_release_channel(cl->dma_chans[stream]);
+		}
+
+		if (!IS_ERR_OR_NULL(cl->clk_parent))
+			clk_put(cl->clk_parent);
+
+		if (!IS_ERR_OR_NULL(cl->pd_dev))
+			dev_pm_domain_detach(cl->pd_dev, true);
+	}
+
+	if (mca->pd_link)
+		device_link_del(mca->pd_link);
+
+	if (!IS_ERR_OR_NULL(mca->pd_dev))
+		dev_pm_domain_detach(mca->pd_dev, true);
+
+	reset_control_assert(mca->rstc);
+}
+
+static int apple_mca_probe(struct platform_device *pdev)
+{
+	struct mca_data *mca;
+	struct mca_cluster *clusters;
+	struct snd_soc_dai_driver *dai_drivers;
+	struct resource *res;
+	void __iomem *base;
+	int nclusters;
+	int ret, i;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	if (resource_size(res) < CLUSTER_STRIDE)
+		return -EINVAL;
+	nclusters = (resource_size(res) - CLUSTER_STRIDE) / CLUSTER_STRIDE + 1;
+
+	mca = devm_kzalloc(&pdev->dev, struct_size(mca, clusters, nclusters),
+			   GFP_KERNEL);
+	if (!mca)
+		return -ENOMEM;
+	mca->dev = &pdev->dev;
+	mca->nclusters = nclusters;
+	platform_set_drvdata(pdev, mca);
+	clusters = mca->clusters;
+
+	mca->switch_base =
+		devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(mca->switch_base))
+		return PTR_ERR(mca->switch_base);
+
+	mca->rstc = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
+	if (IS_ERR(mca->rstc))
+		return PTR_ERR(mca->rstc);
+
+	dai_drivers = devm_kzalloc(
+		&pdev->dev, sizeof(*dai_drivers) * 2 * nclusters, GFP_KERNEL);
+	if (!dai_drivers)
+		return -ENOMEM;
+
+	mca->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, 0);
+	if (IS_ERR(mca->pd_dev))
+		return -EINVAL;
+
+	mca->pd_link = device_link_add(&pdev->dev, mca->pd_dev,
+				       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					       DL_FLAG_RPM_ACTIVE);
+	if (!mca->pd_link) {
+		ret = -EINVAL;
+		/* Prevent an unbalanced reset assert */
+		mca->rstc = NULL;
+		goto err_release;
+	}
+
+	reset_control_deassert(mca->rstc);
+
+	for (i = 0; i < nclusters; i++) {
+		struct mca_cluster *cl = &clusters[i];
+		struct snd_soc_dai_driver *fe =
+			&dai_drivers[mca->nclusters + i];
+		struct snd_soc_dai_driver *be = &dai_drivers[i];
+		int stream;
+
+		cl->host = mca;
+		cl->no = i;
+		cl->base = base + CLUSTER_STRIDE * i;
+		cl->port_driver = -1;
+		cl->clk_parent = of_clk_get(pdev->dev.of_node, i);
+		if (IS_ERR(cl->clk_parent)) {
+			dev_err(&pdev->dev, "unable to obtain clock %d: %ld\n",
+				i, PTR_ERR(cl->clk_parent));
+			ret = PTR_ERR(cl->clk_parent);
+			goto err_release;
+		}
+		cl->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, i + 1);
+		if (IS_ERR(cl->pd_dev)) {
+			dev_err(&pdev->dev,
+				"unable to obtain cluster %d PD: %ld\n", i,
+				PTR_ERR(cl->pd_dev));
+			ret = PTR_ERR(cl->pd_dev);
+			goto err_release;
+		}
+
+		for_each_pcm_streams(stream) {
+			struct dma_chan *chan;
+			bool is_tx = (stream == SNDRV_PCM_STREAM_PLAYBACK);
+#ifndef USE_RXB_FOR_CAPTURE
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%da",
+						    i);
+#else
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%db",
+						    i);
+#endif
+
+			chan = of_dma_request_slave_channel(pdev->dev.of_node,
+							    name);
+			if (IS_ERR(chan)) {
+				if (PTR_ERR(chan) != -EPROBE_DEFER)
+					dev_err(&pdev->dev,
+						"no %s DMA channel: %ld\n",
+						name, PTR_ERR(chan));
+
+				ret = PTR_ERR(chan);
+				goto err_release;
+			}
+
+			cl->dma_chans[stream] = chan;
+		}
+
+		fe->id = i;
+		fe->name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-pcm-%d", i);
+		if (!fe->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		fe->ops = &mca_fe_ops;
+		fe->playback.channels_min = 1;
+		fe->playback.channels_max = 32;
+		fe->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->playback.formats = APPLE_MCA_FMTBITS;
+		fe->capture.channels_min = 1;
+		fe->capture.channels_max = 32;
+		fe->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->capture.formats = APPLE_MCA_FMTBITS;
+		fe->symmetric_rate = 1;
+
+		fe->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d TX", i);
+		fe->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d RX", i);
+
+		if (!fe->playback.stream_name || !fe->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+
+		be->id = i + nclusters;
+		be->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-i2s-%d", i);
+		if (!be->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		be->ops = &mca_be_ops;
+		be->playback.channels_min = 1;
+		be->playback.channels_max = 32;
+		be->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		be->playback.formats = APPLE_MCA_FMTBITS;
+		be->capture.channels_min = 1;
+		be->capture.channels_max = 32;
+		be->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		be->capture.formats = APPLE_MCA_FMTBITS;
+
+		be->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d TX", i);
+		be->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d RX", i);
+		if (!be->playback.stream_name || !be->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+	}
+
+	ret = devm_snd_soc_register_component(&pdev->dev, &mca_component,
+					      dai_drivers, nclusters * 2);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to register ASoC component: %d\n",
+			ret);
+		goto err_release;
+	}
+
+	return 0;
+
+err_release:
+	apple_mca_release(mca);
+	return ret;
+}
+
+static int apple_mca_remove(struct platform_device *pdev)
+{
+	struct mca_data *mca = platform_get_drvdata(pdev);
+
+	apple_mca_release(mca);
+	return 0;
+}
+
+static const struct of_device_id apple_mca_of_match[] = {
+	{ .compatible = "apple,mca", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, apple_mca_of_match);
+
+static struct platform_driver apple_mca_driver = {
+	.driver = {
+		.name = "apple-mca",
+		.of_match_table = apple_mca_of_match,
+	},
+	.probe = apple_mca_probe,
+	.remove = apple_mca_remove,
+};
+module_platform_driver(apple_mca_driver);
+
+MODULE_AUTHOR("Martin Povišer <povik+lin@cutebit.org>");
+MODULE_DESCRIPTION("ASoC Apple MCA driver");
+MODULE_LICENSE("GPL");
-- 
2.33.0


^ permalink raw reply related	[relevance 5%]

* [PATCH v3 3/4] ASoC: apple: mca: Start new platform driver
  @ 2022-08-24 16:07  5%   ` Martin Povišer
  0 siblings, 0 replies; 200+ results
From: Martin Povišer @ 2022-08-24 16:07 UTC (permalink / raw)
  To: Martin Povišer, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Hector Martin, Sven Peter, Philipp Zabel
  Cc: Alyssa Rosenzweig, asahi, alsa-devel, devicetree, linux-kernel

Add ASoC platform driver for the MCA peripheral found on Apple M1 and
other chips.

Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
---
 MAINTAINERS              |    8 +
 sound/soc/Kconfig        |    1 +
 sound/soc/Makefile       |    1 +
 sound/soc/apple/Kconfig  |    9 +
 sound/soc/apple/Makefile |    3 +
 sound/soc/apple/mca.c    | 1148 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 1170 insertions(+)
 create mode 100644 sound/soc/apple/Kconfig
 create mode 100644 sound/soc/apple/Makefile
 create mode 100644 sound/soc/apple/mca.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 8a5012ba6ff9..5f91a6b62f2f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1899,6 +1899,14 @@ F:	include/dt-bindings/pinctrl/apple.h
 F:	include/linux/apple-mailbox.h
 F:	include/linux/soc/apple/*
 
+ARM/APPLE MACHINE SOUND DRIVERS
+M:	Martin Povišer <povik+lin@cutebit.org>
+L:	asahi@lists.linux.dev
+L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/sound/apple,*
+F:	drivers/sound/apple/*
+
 ARM/ARTPEC MACHINE SUPPORT
 M:	Jesper Nilsson <jesper.nilsson@axis.com>
 M:	Lars Persson <lars.persson@axis.com>
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 7d4747b6bab2..848fbae26c3b 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -68,6 +68,7 @@ config SND_SOC_ACPI
 # All the supported SoCs
 source "sound/soc/adi/Kconfig"
 source "sound/soc/amd/Kconfig"
+source "sound/soc/apple/Kconfig"
 source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
 source "sound/soc/bcm/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 453181ef6c94..507eaed1d6a1 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SND_SOC_ACPI) += snd-soc-acpi.o
 obj-$(CONFIG_SND_SOC)	+= snd-soc-core.o
 obj-$(CONFIG_SND_SOC)	+= codecs/
 obj-$(CONFIG_SND_SOC)	+= generic/
+obj-$(CONFIG_SND_SOC)	+= apple/
 obj-$(CONFIG_SND_SOC)	+= adi/
 obj-$(CONFIG_SND_SOC)	+= amd/
 obj-$(CONFIG_SND_SOC)	+= atmel/
diff --git a/sound/soc/apple/Kconfig b/sound/soc/apple/Kconfig
new file mode 100644
index 000000000000..0ba955657e98
--- /dev/null
+++ b/sound/soc/apple/Kconfig
@@ -0,0 +1,9 @@
+config SND_SOC_APPLE_MCA
+	tristate "Apple Silicon MCA driver"
+	depends on ARCH_APPLE || COMPILE_TEST
+	select SND_DMAENGINE_PCM
+	select COMMON_CLK
+	default ARCH_APPLE
+	help
+	  This option enables an ASoC platform driver for MCA peripherals found
+	  on Apple Silicon SoCs.
diff --git a/sound/soc/apple/Makefile b/sound/soc/apple/Makefile
new file mode 100644
index 000000000000..7a30bf452817
--- /dev/null
+++ b/sound/soc/apple/Makefile
@@ -0,0 +1,3 @@
+snd-soc-apple-mca-objs	:= mca.o
+
+obj-$(CONFIG_SND_SOC_APPLE_MCA)	+= snd-soc-apple-mca.o
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
new file mode 100644
index 000000000000..807b85469408
--- /dev/null
+++ b/sound/soc/apple/mca.c
@@ -0,0 +1,1148 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Apple SoCs MCA driver
+//
+// Copyright (C) The Asahi Linux Contributors
+//
+// The MCA peripheral is made up of a number of identical units called clusters.
+// Each cluster has its separate clock parent, SYNC signal generator, carries
+// four SERDES units and has a dedicated I2S port on the SoC's periphery.
+//
+// The clusters can operate independently, or can be combined together in a
+// configurable manner. We mostly treat them as self-contained independent
+// units and don't configure any cross-cluster connections except for the I2S
+// ports. The I2S ports can be routed to any of the clusters (irrespective
+// of their native cluster). We map this onto ASoC's (DPCM) notion of backend
+// and frontend DAIs. The 'cluster guts' are frontends which are dynamically
+// routed to backend I2S ports.
+//
+// DAI references in devicetree are resolved to backends. The routing between
+// frontends and backends is determined by the machine driver in the DAPM paths
+// it supplies.
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_clk.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+
+#define USE_RXB_FOR_CAPTURE
+
+/* Relative to cluster base */
+#define REG_STATUS		0x0
+#define STATUS_MCLK_EN		BIT(0)
+#define REG_MCLK_CONF		0x4
+#define MCLK_CONF_DIV		GENMASK(11, 8)
+
+#define REG_SYNCGEN_STATUS	0x100
+#define SYNCGEN_STATUS_EN	BIT(0)
+#define REG_SYNCGEN_MCLK_SEL	0x104
+#define SYNCGEN_MCLK_SEL	GENMASK(3, 0)
+#define REG_SYNCGEN_HI_PERIOD	0x108
+#define REG_SYNCGEN_LO_PERIOD	0x10c
+
+#define REG_PORT_ENABLES	0x600
+#define PORT_ENABLES_CLOCKS	GENMASK(2, 1)
+#define PORT_ENABLES_TX_DATA	BIT(3)
+#define REG_PORT_CLOCK_SEL	0x604
+#define PORT_CLOCK_SEL		GENMASK(11, 8)
+#define REG_PORT_DATA_SEL	0x608
+#define PORT_DATA_SEL_TXA(cl)	(1 << ((cl)*2))
+#define PORT_DATA_SEL_TXB(cl)	(2 << ((cl)*2))
+
+#define REG_INTSTATE		0x700
+#define REG_INTMASK		0x704
+
+/* Bases of serdes units (relative to cluster) */
+#define CLUSTER_RXA_OFF	0x200
+#define CLUSTER_TXA_OFF	0x300
+#define CLUSTER_RXB_OFF	0x400
+#define CLUSTER_TXB_OFF	0x500
+
+#define CLUSTER_TX_OFF	CLUSTER_TXA_OFF
+
+#ifndef USE_RXB_FOR_CAPTURE
+#define CLUSTER_RX_OFF	CLUSTER_RXA_OFF
+#else
+#define CLUSTER_RX_OFF	CLUSTER_RXB_OFF
+#endif
+
+/* Relative to serdes unit base */
+#define REG_SERDES_STATUS	0x00
+#define SERDES_STATUS_EN	BIT(0)
+#define SERDES_STATUS_RST	BIT(1)
+#define REG_TX_SERDES_CONF	0x04
+#define REG_RX_SERDES_CONF	0x08
+#define SERDES_CONF_NCHANS	GENMASK(3, 0)
+#define SERDES_CONF_WIDTH_MASK	GENMASK(8, 4)
+#define SERDES_CONF_WIDTH_16BIT 0x40
+#define SERDES_CONF_WIDTH_20BIT 0x80
+#define SERDES_CONF_WIDTH_24BIT 0xc0
+#define SERDES_CONF_WIDTH_32BIT 0x100
+#define SERDES_CONF_BCLK_POL	0x400
+#define SERDES_CONF_LSB_FIRST	0x800
+#define SERDES_CONF_UNK1	BIT(12)
+#define SERDES_CONF_UNK2	BIT(13)
+#define SERDES_CONF_UNK3	BIT(14)
+#define SERDES_CONF_NO_DATA_FEEDBACK	BIT(15)
+#define SERDES_CONF_SYNC_SEL	GENMASK(18, 16)
+#define SERDES_CONF_SOME_RST	BIT(19)
+#define REG_TX_SERDES_BITSTART	0x08
+#define REG_RX_SERDES_BITSTART	0x0c
+#define REG_TX_SERDES_SLOTMASK	0x0c
+#define REG_RX_SERDES_SLOTMASK	0x10
+#define REG_RX_SERDES_PORT	0x04
+
+/* Relative to switch base */
+#define REG_DMA_ADAPTER_A(cl)	(0x8000 * (cl))
+#define REG_DMA_ADAPTER_B(cl)	(0x8000 * (cl) + 0x4000)
+#define DMA_ADAPTER_TX_LSB_PAD	GENMASK(4, 0)
+#define DMA_ADAPTER_TX_NCHANS	GENMASK(6, 5)
+#define DMA_ADAPTER_RX_MSB_PAD	GENMASK(12, 8)
+#define DMA_ADAPTER_RX_NCHANS	GENMASK(14, 13)
+#define DMA_ADAPTER_NCHANS	GENMASK(22, 20)
+
+#define SWITCH_STRIDE	0x8000
+#define CLUSTER_STRIDE	0x4000
+
+#define MAX_NCLUSTERS	6
+
+#define APPLE_MCA_FMTBITS (SNDRV_PCM_FMTBIT_S16_LE | \
+			   SNDRV_PCM_FMTBIT_S24_LE | \
+			   SNDRV_PCM_FMTBIT_S32_LE)
+
+struct mca_cluster {
+	int no;
+	__iomem void *base;
+	struct mca_data *host;
+	struct device *pd_dev;
+	struct clk *clk_parent;
+	struct dma_chan *dma_chans[SNDRV_PCM_STREAM_LAST + 1];
+
+	bool port_started[SNDRV_PCM_STREAM_LAST + 1];
+	int port_driver; /* The cluster driving this cluster's port */
+
+	bool clocks_in_use[SNDRV_PCM_STREAM_LAST + 1];
+	struct device_link *pd_link;
+
+	unsigned int bclk_ratio;
+
+	/* Masks etc. picked up via the set_tdm_slot method */
+	int tdm_slots;
+	int tdm_slot_width;
+	unsigned int tdm_tx_mask;
+	unsigned int tdm_rx_mask;
+};
+
+struct mca_data {
+	struct device *dev;
+
+	__iomem void *switch_base;
+
+	struct device *pd_dev;
+	struct reset_control *rstc;
+	struct device_link *pd_link;
+
+	int nclusters;
+	struct mca_cluster clusters[];
+};
+
+static void mca_modify(struct mca_cluster *cl, int regoffset, u32 mask, u32 val)
+{
+	__iomem void *ptr = cl->base + regoffset;
+	u32 newval;
+
+	newval = (val & mask) | (readl_relaxed(ptr) & ~mask);
+	writel_relaxed(newval, ptr);
+}
+
+/*
+ * Get the cluster of FE or BE DAI
+ */
+static struct mca_cluster *mca_dai_to_cluster(struct snd_soc_dai *dai)
+{
+	struct mca_data *mca = snd_soc_dai_get_drvdata(dai);
+	/*
+	 * FE DAIs are         0 ... nclusters - 1
+	 * BE DAIs are nclusters ... 2*nclusters - 1
+	 */
+	int cluster_no = dai->id % mca->nclusters;
+
+	return &mca->clusters[cluster_no];
+}
+
+/* called before PCM trigger */
+static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
+				 struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+	int serdes_conf =
+		serdes_unit + (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_RST);
+		mca_modify(cl, serdes_conf, SERDES_CONF_SOME_RST,
+			   SERDES_CONF_SOME_RST);
+		readl_relaxed(cl->base + serdes_conf);
+		mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
+		WARN_ON(readl_relaxed(cl->base + REG_SERDES_STATUS) &
+			SERDES_STATUS_RST);
+		break;
+	default:
+		break;
+	}
+}
+
+static int mca_fe_trigger(struct snd_pcm_substream *substream, int cmd,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_EN);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mca_fe_enable_clocks(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	int ret;
+
+	ret = clk_prepare_enable(cl->clk_parent);
+	if (ret) {
+		dev_err(mca->dev,
+			"cluster %d: unable to enable clock parent: %d\n",
+			cl->no, ret);
+		return ret;
+	}
+
+	/*
+	 * We can't power up the device earlier than this because
+	 * the power state driver would error out on seeing the device
+	 * as clock-gated.
+	 */
+	cl->pd_link = device_link_add(mca->dev, cl->pd_dev,
+				      DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					      DL_FLAG_RPM_ACTIVE);
+	if (!cl->pd_link) {
+		dev_err(mca->dev,
+			"cluster %d: unable to prop-up power domain\n", cl->no);
+		clk_disable_unprepare(cl->clk_parent);
+		return -EINVAL;
+	}
+
+	writel_relaxed(cl->no + 1, cl->base + REG_SYNCGEN_MCLK_SEL);
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN,
+		   SYNCGEN_STATUS_EN);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, STATUS_MCLK_EN);
+
+	return 0;
+}
+
+static void mca_fe_disable_clocks(struct mca_cluster *cl)
+{
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN, 0);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, 0);
+
+	device_link_del(cl->pd_link);
+	clk_disable_unprepare(cl->clk_parent);
+}
+
+static bool mca_fe_clocks_in_use(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *be_cl;
+	int stream, i;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		be_cl = &mca->clusters[i];
+
+		if (be_cl->port_driver != cl->no)
+			continue;
+
+		for_each_pcm_streams(stream)
+			if (be_cl->clocks_in_use[stream])
+				return true;
+	}
+	return false;
+}
+
+static int mca_be_prepare(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+	int ret;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+
+	/*
+	 * Typically the CODECs we are paired with will require clocks
+	 * to be present at time of unmute with the 'mute_stream' op
+	 * or at time of DAPM widget power-up. We need to enable clocks
+	 * here at the latest (frontend prepare would be too late).
+	 */
+	if (!mca_fe_clocks_in_use(fe_cl)) {
+		ret = mca_fe_enable_clocks(fe_cl);
+		if (ret < 0)
+			return ret;
+	}
+
+	cl->clocks_in_use[substream->stream] = true;
+
+	return 0;
+}
+
+static int mca_be_hw_free(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+	if (!mca_fe_clocks_in_use(fe_cl))
+		return 0; /* Nothing to do */
+
+	cl->clocks_in_use[substream->stream] = false;
+
+	if (!mca_fe_clocks_in_use(fe_cl))
+		mca_fe_disable_clocks(fe_cl);
+
+	return 0;
+}
+
+static unsigned int mca_crop_mask(unsigned int mask, int nchans)
+{
+	while (hweight32(mask) > nchans)
+		mask &= ~(1 << __fls(mask));
+
+	return mask;
+}
+
+static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
+				unsigned int mask, int slots, int nchans,
+				int slot_width, bool is_tx, int port)
+{
+	__iomem void *serdes_base = cl->base + serdes_unit;
+	u32 serdes_conf, serdes_conf_mask;
+
+	serdes_conf_mask = SERDES_CONF_WIDTH_MASK | SERDES_CONF_NCHANS;
+	serdes_conf = FIELD_PREP(SERDES_CONF_NCHANS, max(slots, 1) - 1);
+	switch (slot_width) {
+	case 16:
+		serdes_conf |= SERDES_CONF_WIDTH_16BIT;
+		break;
+	case 20:
+		serdes_conf |= SERDES_CONF_WIDTH_20BIT;
+		break;
+	case 24:
+		serdes_conf |= SERDES_CONF_WIDTH_24BIT;
+		break;
+	case 32:
+		serdes_conf |= SERDES_CONF_WIDTH_32BIT;
+		break;
+	default:
+		goto err;
+	}
+
+	serdes_conf_mask |= SERDES_CONF_SYNC_SEL;
+	serdes_conf |= FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1);
+
+	if (is_tx) {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_UNK3;
+	} else {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3 |
+				    SERDES_CONF_NO_DATA_FEEDBACK;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_NO_DATA_FEEDBACK;
+	}
+
+	mca_modify(cl,
+		   serdes_unit +
+			   (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF),
+		   serdes_conf_mask, serdes_conf);
+
+	if (is_tx) {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x8);
+		writel_relaxed(~((u32)mask),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0xc);
+	} else {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_RX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_RX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(1 << port,
+			       serdes_base + REG_RX_SERDES_PORT);
+	}
+
+	return 0;
+
+err:
+	dev_err(cl->host->dev,
+		"unsupported SERDES configuration requested (mask=0x%x slots=%d slot_width=%d)\n",
+		mask, slots, slot_width);
+	return -EINVAL;
+}
+
+static int mca_fe_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+			       unsigned int rx_mask, int slots, int slot_width)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->tdm_slots = slots;
+	cl->tdm_slot_width = slot_width;
+	cl->tdm_tx_mask = tx_mask;
+	cl->tdm_rx_mask = rx_mask;
+
+	return 0;
+}
+
+static int mca_fe_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	bool fpol_inv = false;
+	u32 serdes_conf = 0;
+	u32 bitstart;
+
+	if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) !=
+	    SND_SOC_DAIFMT_BP_FP)
+		goto err;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		fpol_inv = 0;
+		bitstart = 1;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		fpol_inv = 1;
+		bitstart = 0;
+		break;
+	default:
+		goto err;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_IF:
+	case SND_SOC_DAIFMT_IB_IF:
+		fpol_inv ^= 1;
+		break;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+	case SND_SOC_DAIFMT_NB_IF:
+		serdes_conf |= SERDES_CONF_BCLK_POL;
+		break;
+	}
+
+	if (!fpol_inv)
+		goto err;
+
+	mca_modify(cl, CLUSTER_TX_OFF + REG_TX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	mca_modify(cl, CLUSTER_RX_OFF + REG_RX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_TX_OFF + REG_TX_SERDES_BITSTART);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_RX_OFF + REG_RX_SERDES_BITSTART);
+
+	return 0;
+
+err:
+	dev_err(mca->dev, "unsupported DAI format (0x%x) requested\n", fmt);
+	return -EINVAL;
+}
+
+static int mca_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->bclk_ratio = ratio;
+
+	return 0;
+}
+
+static int mca_fe_get_port(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *be;
+	struct snd_soc_dpcm *dpcm;
+
+	be = NULL;
+	for_each_dpcm_be(fe, substream->stream, dpcm) {
+		be = dpcm->be;
+		break;
+	}
+
+	if (!be)
+		return -EINVAL;
+
+	return mca_dai_to_cluster(asoc_rtd_to_cpu(be, 0))->no;
+}
+
+static int mca_fe_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct device *dev = mca->dev;
+	unsigned int samp_rate = params_rate(params);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	bool refine_tdm = false;
+	unsigned long bclk_ratio;
+	unsigned int tdm_slots, tdm_slot_width, tdm_mask;
+	u32 regval, pad;
+	int ret, port, nchans_ceiled;
+
+	if (!cl->tdm_slot_width) {
+		/*
+		 * We were not given TDM settings from above, set initial
+		 * guesses which will later be refined.
+		 */
+		tdm_slot_width = params_width(params);
+		tdm_slots = params_channels(params);
+		refine_tdm = true;
+	} else {
+		tdm_slot_width = cl->tdm_slot_width;
+		tdm_slots = cl->tdm_slots;
+		tdm_mask = is_tx ? cl->tdm_tx_mask : cl->tdm_rx_mask;
+	}
+
+	if (cl->bclk_ratio)
+		bclk_ratio = cl->bclk_ratio;
+	else
+		bclk_ratio = tdm_slot_width * tdm_slots;
+
+	if (refine_tdm) {
+		int nchannels = params_channels(params);
+
+		if (nchannels > 2) {
+			dev_err(dev, "missing TDM for stream with two or more channels\n");
+			return -EINVAL;
+		}
+
+		if ((bclk_ratio % nchannels) != 0) {
+			dev_err(dev, "BCLK ratio (%ld) not divisible by no. of channels (%d)\n",
+				bclk_ratio, nchannels);
+			return -EINVAL;
+		}
+
+		tdm_slot_width = bclk_ratio / nchannels;
+
+		if (tdm_slot_width > 32 && nchannels == 1)
+			tdm_slot_width = 32;
+
+		if (tdm_slot_width < params_width(params)) {
+			dev_err(dev, "TDM slots too narrow (tdm=%d params=%d)\n",
+				tdm_slot_width, params_width(params));
+			return -EINVAL;
+		}
+
+		tdm_mask = (1 << tdm_slots) - 1;
+	}
+
+	port = mca_fe_get_port(substream);
+	if (port < 0)
+		return port;
+
+	ret = mca_configure_serdes(cl, is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF,
+				   tdm_mask, tdm_slots, params_channels(params),
+				   tdm_slot_width, is_tx, port);
+	if (ret)
+		return ret;
+
+	pad = 32 - params_width(params);
+
+	/*
+	 * TODO: Here the register semantics aren't clear.
+	 */
+	nchans_ceiled = min_t(int, params_channels(params), 4);
+	regval = FIELD_PREP(DMA_ADAPTER_NCHANS, nchans_ceiled) |
+		 FIELD_PREP(DMA_ADAPTER_TX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_RX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_TX_LSB_PAD, pad) |
+		 FIELD_PREP(DMA_ADAPTER_RX_MSB_PAD, pad);
+
+#ifndef USE_RXB_FOR_CAPTURE
+	writel_relaxed(regval, mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+#else
+	if (is_tx)
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+	else
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_B(cl->no));
+#endif
+
+	if (!mca_fe_clocks_in_use(cl)) {
+		/*
+		 * Set up FSYNC duty cycle as even as possible.
+		 */
+		writel_relaxed((bclk_ratio / 2) - 1,
+			       cl->base + REG_SYNCGEN_HI_PERIOD);
+		writel_relaxed(((bclk_ratio + 1) / 2) - 1,
+			       cl->base + REG_SYNCGEN_LO_PERIOD);
+		writel_relaxed(FIELD_PREP(MCLK_CONF_DIV, 0x1),
+			       cl->base + REG_MCLK_CONF);
+
+		ret = clk_set_rate(cl->clk_parent, bclk_ratio * samp_rate);
+		if (ret) {
+			dev_err(mca->dev, "cluster %d: unable to set clock parent: %d\n",
+				cl->no, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops mca_fe_ops = {
+	.set_fmt = mca_fe_set_fmt,
+	.set_bclk_ratio = mca_set_bclk_ratio,
+	.set_tdm_slot = mca_fe_set_tdm_slot,
+	.hw_params = mca_fe_hw_params,
+	.trigger = mca_fe_trigger,
+};
+
+static bool mca_be_started(struct mca_cluster *cl)
+{
+	int stream;
+
+	for_each_pcm_streams(stream)
+		if (cl->port_started[stream])
+			return true;
+	return false;
+}
+
+static int mca_be_startup(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *be = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *fe;
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_cluster *fe_cl;
+	struct mca_data *mca = cl->host;
+	struct snd_soc_dpcm *dpcm;
+
+	fe = NULL;
+
+	for_each_dpcm_fe(be, substream->stream, dpcm) {
+		if (fe && dpcm->fe != fe) {
+			dev_err(mca->dev, "many FE per one BE unsupported\n");
+			return -EINVAL;
+		}
+
+		fe = dpcm->fe;
+	}
+
+	if (!fe)
+		return -EINVAL;
+
+	fe_cl = mca_dai_to_cluster(asoc_rtd_to_cpu(fe, 0));
+
+	if (mca_be_started(cl)) {
+		/*
+		 * Port is already started in the other direction.
+		 * Make sure there isn't a conflict with another cluster
+		 * driving the port.
+		 */
+		if (cl->port_driver != fe_cl->no)
+			return -EINVAL;
+
+		cl->port_started[substream->stream] = true;
+		return 0;
+	}
+
+	writel_relaxed(PORT_ENABLES_CLOCKS | PORT_ENABLES_TX_DATA,
+		       cl->base + REG_PORT_ENABLES);
+	writel_relaxed(FIELD_PREP(PORT_CLOCK_SEL, fe_cl->no + 1),
+		       cl->base + REG_PORT_CLOCK_SEL);
+	writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no),
+		       cl->base + REG_PORT_DATA_SEL);
+	cl->port_driver = fe_cl->no;
+	cl->port_started[substream->stream] = true;
+
+	return 0;
+}
+
+static void mca_be_shutdown(struct snd_pcm_substream *substream,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->port_started[substream->stream] = false;
+
+	if (!mca_be_started(cl)) {
+		/*
+		 * Were we the last direction to shutdown?
+		 * Turn off the lights.
+		 */
+		writel_relaxed(0, cl->base + REG_PORT_ENABLES);
+		writel_relaxed(0, cl->base + REG_PORT_DATA_SEL);
+		cl->port_driver = -1;
+	}
+}
+
+static const struct snd_soc_dai_ops mca_be_ops = {
+	.prepare = mca_be_prepare,
+	.hw_free = mca_be_hw_free,
+	.startup = mca_be_startup,
+	.shutdown = mca_be_shutdown,
+};
+
+static int mca_set_runtime_hwparams(struct snd_soc_component *component,
+				    struct snd_pcm_substream *substream,
+				    struct dma_chan *chan)
+{
+	struct device *dma_dev = chan->device->dev;
+	struct snd_dmaengine_dai_dma_data dma_data = {};
+	int ret;
+
+	struct snd_pcm_hardware hw;
+
+	memset(&hw, 0, sizeof(hw));
+
+	hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+		  SNDRV_PCM_INFO_INTERLEAVED;
+	hw.periods_min = 2;
+	hw.periods_max = UINT_MAX;
+	hw.period_bytes_min = 256;
+	hw.period_bytes_max = dma_get_max_seg_size(dma_dev);
+	hw.buffer_bytes_max = SIZE_MAX;
+	hw.fifo_size = 16;
+
+	ret = snd_dmaengine_pcm_refine_runtime_hwparams(substream, &dma_data,
+							&hw, chan);
+
+	if (ret)
+		return ret;
+
+	return snd_soc_set_runtime_hwparams(substream, &hw);
+}
+
+static int mca_pcm_open(struct snd_soc_component *component,
+			struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	struct dma_chan *chan = cl->dma_chans[substream->stream];
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	ret = mca_set_runtime_hwparams(component, substream, chan);
+	if (ret)
+		return ret;
+
+	return snd_dmaengine_pcm_open(substream, chan);
+}
+
+static int mca_hw_params(struct snd_soc_component *component,
+			 struct snd_pcm_substream *substream,
+			 struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
+	struct dma_slave_config slave_config;
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	memset(&slave_config, 0, sizeof(slave_config));
+	ret = snd_hwparams_to_dma_slave_config(substream, params,
+					       &slave_config);
+	if (ret < 0)
+		return ret;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		slave_config.dst_port_window_size =
+			min_t(u32, params_channels(params), 4);
+	else
+		slave_config.src_port_window_size =
+			min_t(u32, params_channels(params), 4);
+
+	return dmaengine_slave_config(chan, &slave_config);
+}
+
+static int mca_close(struct snd_soc_component *component,
+		     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	return snd_dmaengine_pcm_close(substream);
+}
+
+static int mca_trigger(struct snd_soc_component *component,
+		       struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	/*
+	 * Before we do the PCM trigger proper, insert an opportunity
+	 * to reset the frontend's SERDES.
+	 */
+	mca_fe_early_trigger(substream, cmd, asoc_rtd_to_cpu(rtd, 0));
+
+	return snd_dmaengine_pcm_trigger(substream, cmd);
+}
+
+static snd_pcm_uframes_t mca_pointer(struct snd_soc_component *component,
+				     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return -ENOTSUPP;
+
+	return snd_dmaengine_pcm_pointer(substream);
+}
+
+static int mca_pcm_new(struct snd_soc_component *component,
+		       struct snd_soc_pcm_runtime *rtd)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	unsigned int i;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	for_each_pcm_streams(i) {
+		struct snd_pcm_substream *substream =
+			rtd->pcm->streams[i].substream;
+		struct dma_chan *chan = cl->dma_chans[i];
+
+		if (!substream)
+			continue;
+
+		if (!chan) {
+			dev_err(component->dev, "missing DMA channel for stream %d on SERDES %d\n",
+				i, cl->no);
+			return -EINVAL;
+		}
+
+		snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV_IRAM,
+					   chan->device->dev, 512 * 1024 * 6,
+					   SIZE_MAX);
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_component_driver mca_component = {
+	.name = "apple-mca",
+	.open = mca_pcm_open,
+	.close = mca_close,
+	.hw_params = mca_hw_params,
+	.trigger = mca_trigger,
+	.pointer = mca_pointer,
+	.pcm_construct = mca_pcm_new,
+};
+
+static void apple_mca_release(struct mca_data *mca)
+{
+	int i, stream;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		struct mca_cluster *cl = &mca->clusters[i];
+
+		for_each_pcm_streams(stream) {
+			if (IS_ERR_OR_NULL(cl->dma_chans[stream]))
+				continue;
+
+			dma_release_channel(cl->dma_chans[stream]);
+		}
+
+		if (!IS_ERR_OR_NULL(cl->clk_parent))
+			clk_put(cl->clk_parent);
+
+		if (!IS_ERR_OR_NULL(cl->pd_dev))
+			dev_pm_domain_detach(cl->pd_dev, true);
+	}
+
+	if (mca->pd_link)
+		device_link_del(mca->pd_link);
+
+	if (!IS_ERR_OR_NULL(mca->pd_dev))
+		dev_pm_domain_detach(mca->pd_dev, true);
+
+	reset_control_assert(mca->rstc);
+}
+
+static int apple_mca_probe(struct platform_device *pdev)
+{
+	struct mca_data *mca;
+	struct mca_cluster *clusters;
+	struct snd_soc_dai_driver *dai_drivers;
+	struct resource *res;
+	void __iomem *base;
+	int nclusters;
+	int ret, i;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	if (resource_size(res) < CLUSTER_STRIDE)
+		return -EINVAL;
+	nclusters = (resource_size(res) - CLUSTER_STRIDE) / CLUSTER_STRIDE + 1;
+
+	mca = devm_kzalloc(&pdev->dev, struct_size(mca, clusters, nclusters),
+			   GFP_KERNEL);
+	if (!mca)
+		return -ENOMEM;
+	mca->dev = &pdev->dev;
+	mca->nclusters = nclusters;
+	platform_set_drvdata(pdev, mca);
+	clusters = mca->clusters;
+
+	mca->switch_base =
+		devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(mca->switch_base))
+		return PTR_ERR(mca->switch_base);
+
+	mca->rstc = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
+	if (IS_ERR(mca->rstc))
+		return PTR_ERR(mca->rstc);
+
+	dai_drivers = devm_kzalloc(
+		&pdev->dev, sizeof(*dai_drivers) * 2 * nclusters, GFP_KERNEL);
+	if (!dai_drivers)
+		return -ENOMEM;
+
+	mca->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, 0);
+	if (IS_ERR(mca->pd_dev))
+		return -EINVAL;
+
+	mca->pd_link = device_link_add(&pdev->dev, mca->pd_dev,
+				       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					       DL_FLAG_RPM_ACTIVE);
+	if (!mca->pd_link) {
+		ret = -EINVAL;
+		/* Prevent an unbalanced reset assert */
+		mca->rstc = NULL;
+		goto err_release;
+	}
+
+	reset_control_deassert(mca->rstc);
+
+	for (i = 0; i < nclusters; i++) {
+		struct mca_cluster *cl = &clusters[i];
+		struct snd_soc_dai_driver *fe =
+			&dai_drivers[mca->nclusters + i];
+		struct snd_soc_dai_driver *be = &dai_drivers[i];
+		int stream;
+
+		cl->host = mca;
+		cl->no = i;
+		cl->base = base + CLUSTER_STRIDE * i;
+		cl->port_driver = -1;
+		cl->clk_parent = of_clk_get(pdev->dev.of_node, i);
+		if (IS_ERR(cl->clk_parent)) {
+			dev_err(&pdev->dev, "unable to obtain clock %d: %ld\n",
+				i, PTR_ERR(cl->clk_parent));
+			ret = PTR_ERR(cl->clk_parent);
+			goto err_release;
+		}
+		cl->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, i + 1);
+		if (IS_ERR(cl->pd_dev)) {
+			dev_err(&pdev->dev,
+				"unable to obtain cluster %d PD: %ld\n", i,
+				PTR_ERR(cl->pd_dev));
+			ret = PTR_ERR(cl->pd_dev);
+			goto err_release;
+		}
+
+		for_each_pcm_streams(stream) {
+			struct dma_chan *chan;
+			bool is_tx = (stream == SNDRV_PCM_STREAM_PLAYBACK);
+#ifndef USE_RXB_FOR_CAPTURE
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%da",
+						    i);
+#else
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%db",
+						    i);
+#endif
+
+			chan = of_dma_request_slave_channel(pdev->dev.of_node,
+							    name);
+			if (IS_ERR(chan)) {
+				if (PTR_ERR(chan) != -EPROBE_DEFER)
+					dev_err(&pdev->dev,
+						"no %s DMA channel: %ld\n",
+						name, PTR_ERR(chan));
+
+				ret = PTR_ERR(chan);
+				goto err_release;
+			}
+
+			cl->dma_chans[stream] = chan;
+		}
+
+		fe->id = i;
+		fe->name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-pcm-%d", i);
+		if (!fe->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		fe->ops = &mca_fe_ops;
+		fe->playback.channels_min = 1;
+		fe->playback.channels_max = 32;
+		fe->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->playback.formats = APPLE_MCA_FMTBITS;
+		fe->capture.channels_min = 1;
+		fe->capture.channels_max = 32;
+		fe->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->capture.formats = APPLE_MCA_FMTBITS;
+		fe->symmetric_rate = 1;
+
+		fe->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d TX", i);
+		fe->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d RX", i);
+
+		if (!fe->playback.stream_name || !fe->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+
+		be->id = i + nclusters;
+		be->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-i2s-%d", i);
+		if (!be->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		be->ops = &mca_be_ops;
+		be->playback.channels_min = 1;
+		be->playback.channels_max = 32;
+		be->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		be->playback.formats = APPLE_MCA_FMTBITS;
+		be->capture.channels_min = 1;
+		be->capture.channels_max = 32;
+		be->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		be->capture.formats = APPLE_MCA_FMTBITS;
+
+		be->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d TX", i);
+		be->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d RX", i);
+		if (!be->playback.stream_name || !be->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+	}
+
+	ret = devm_snd_soc_register_component(&pdev->dev, &mca_component,
+					      dai_drivers, nclusters * 2);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to register ASoC component: %d\n",
+			ret);
+		goto err_release;
+	}
+
+	return 0;
+
+err_release:
+	apple_mca_release(mca);
+	return ret;
+}
+
+static int apple_mca_remove(struct platform_device *pdev)
+{
+	struct mca_data *mca = platform_get_drvdata(pdev);
+
+	apple_mca_release(mca);
+	return 0;
+}
+
+static const struct of_device_id apple_mca_of_match[] = {
+	{ .compatible = "apple,mca", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, apple_mca_of_match);
+
+static struct platform_driver apple_mca_driver = {
+	.driver = {
+		.name = "apple-mca",
+		.of_match_table = apple_mca_of_match,
+	},
+	.probe = apple_mca_probe,
+	.remove = apple_mca_remove,
+};
+module_platform_driver(apple_mca_driver);
+
+MODULE_AUTHOR("Martin Povišer <povik+lin@cutebit.org>");
+MODULE_DESCRIPTION("ASoC Apple MCA driver");
+MODULE_LICENSE("GPL");
-- 
2.33.0


^ permalink raw reply related	[relevance 5%]

* [PATCH v2 3/4] ASoC: apple: mca: Start new platform driver
@ 2022-08-19 12:54  5%   ` Martin Povišer
  0 siblings, 0 replies; 200+ results
From: Martin Povišer @ 2022-08-19 12:54 UTC (permalink / raw)
  To: Martin Povišer, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Hector Martin, Sven Peter, Philipp Zabel
  Cc: devicetree, alsa-devel, asahi, Alyssa Rosenzweig, linux-kernel

Add ASoC platform driver for the MCA peripheral found on Apple M1 and
other chips.

Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
---
 MAINTAINERS              |    8 +
 sound/soc/Kconfig        |    1 +
 sound/soc/Makefile       |    1 +
 sound/soc/apple/Kconfig  |    9 +
 sound/soc/apple/Makefile |    3 +
 sound/soc/apple/mca.c    | 1149 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 1171 insertions(+)
 create mode 100644 sound/soc/apple/Kconfig
 create mode 100644 sound/soc/apple/Makefile
 create mode 100644 sound/soc/apple/mca.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 8a5012ba6ff9..5f91a6b62f2f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1899,6 +1899,14 @@ F:	include/dt-bindings/pinctrl/apple.h
 F:	include/linux/apple-mailbox.h
 F:	include/linux/soc/apple/*
 
+ARM/APPLE MACHINE SOUND DRIVERS
+M:	Martin Povišer <povik+lin@cutebit.org>
+L:	asahi@lists.linux.dev
+L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/sound/apple,*
+F:	drivers/sound/apple/*
+
 ARM/ARTPEC MACHINE SUPPORT
 M:	Jesper Nilsson <jesper.nilsson@axis.com>
 M:	Lars Persson <lars.persson@axis.com>
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 7d4747b6bab2..848fbae26c3b 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -68,6 +68,7 @@ config SND_SOC_ACPI
 # All the supported SoCs
 source "sound/soc/adi/Kconfig"
 source "sound/soc/amd/Kconfig"
+source "sound/soc/apple/Kconfig"
 source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
 source "sound/soc/bcm/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 453181ef6c94..507eaed1d6a1 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SND_SOC_ACPI) += snd-soc-acpi.o
 obj-$(CONFIG_SND_SOC)	+= snd-soc-core.o
 obj-$(CONFIG_SND_SOC)	+= codecs/
 obj-$(CONFIG_SND_SOC)	+= generic/
+obj-$(CONFIG_SND_SOC)	+= apple/
 obj-$(CONFIG_SND_SOC)	+= adi/
 obj-$(CONFIG_SND_SOC)	+= amd/
 obj-$(CONFIG_SND_SOC)	+= atmel/
diff --git a/sound/soc/apple/Kconfig b/sound/soc/apple/Kconfig
new file mode 100644
index 000000000000..0ba955657e98
--- /dev/null
+++ b/sound/soc/apple/Kconfig
@@ -0,0 +1,9 @@
+config SND_SOC_APPLE_MCA
+	tristate "Apple Silicon MCA driver"
+	depends on ARCH_APPLE || COMPILE_TEST
+	select SND_DMAENGINE_PCM
+	select COMMON_CLK
+	default ARCH_APPLE
+	help
+	  This option enables an ASoC platform driver for MCA peripherals found
+	  on Apple Silicon SoCs.
diff --git a/sound/soc/apple/Makefile b/sound/soc/apple/Makefile
new file mode 100644
index 000000000000..7a30bf452817
--- /dev/null
+++ b/sound/soc/apple/Makefile
@@ -0,0 +1,3 @@
+snd-soc-apple-mca-objs	:= mca.o
+
+obj-$(CONFIG_SND_SOC_APPLE_MCA)	+= snd-soc-apple-mca.o
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
new file mode 100644
index 000000000000..6eeb35d49986
--- /dev/null
+++ b/sound/soc/apple/mca.c
@@ -0,0 +1,1149 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Apple SoCs MCA driver
+ *
+ * Copyright (C) The Asahi Linux Contributors
+ *
+ * The MCA peripheral is made up of a number of identical units called clusters.
+ * Each cluster has its separate clock parent, SYNC signal generator, carries
+ * four SERDES units and has a dedicated I2S port on the SoC's periphery.
+ *
+ * The clusters can operate independently, or can be combined together in a
+ * configurable manner. We mostly treat them as self-contained independent
+ * units and don't configure any cross-cluster connections except for the I2S
+ * ports. The I2S ports can be routed to any of the clusters (irrespective
+ * of their native cluster). We map this onto ASoC's (DPCM) notion of backend
+ * and frontend DAIs. The 'cluster guts' are frontends which are dynamically
+ * routed to backend I2S ports.
+ *
+ * DAI references in devicetree are resolved to backends. The routing between
+ * frontends and backends is determined by the machine driver in the DAPM paths
+ * it supplies.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_clk.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+
+#define USE_RXB_FOR_CAPTURE
+
+/* Relative to cluster base */
+#define REG_STATUS		0x0
+#define STATUS_MCLK_EN		BIT(0)
+#define REG_MCLK_CONF		0x4
+#define MCLK_CONF_DIV		GENMASK(11, 8)
+
+#define REG_SYNCGEN_STATUS	0x100
+#define SYNCGEN_STATUS_EN	BIT(0)
+#define REG_SYNCGEN_MCLK_SEL	0x104
+#define SYNCGEN_MCLK_SEL	GENMASK(3, 0)
+#define REG_SYNCGEN_HI_PERIOD	0x108
+#define REG_SYNCGEN_LO_PERIOD	0x10c
+
+#define REG_PORT_ENABLES	0x600
+#define PORT_ENABLES_CLOCKS	GENMASK(2, 1)
+#define PORT_ENABLES_TX_DATA	BIT(3)
+#define REG_PORT_CLOCK_SEL	0x604
+#define PORT_CLOCK_SEL		GENMASK(11, 8)
+#define REG_PORT_DATA_SEL	0x608
+#define PORT_DATA_SEL_TXA(cl)	(1 << ((cl)*2))
+#define PORT_DATA_SEL_TXB(cl)	(2 << ((cl)*2))
+
+#define REG_INTSTATE		0x700
+#define REG_INTMASK		0x704
+
+/* Bases of serdes units (relative to cluster) */
+#define CLUSTER_RXA_OFF	0x200
+#define CLUSTER_TXA_OFF	0x300
+#define CLUSTER_RXB_OFF	0x400
+#define CLUSTER_TXB_OFF	0x500
+
+#define CLUSTER_TX_OFF	CLUSTER_TXA_OFF
+
+#ifndef USE_RXB_FOR_CAPTURE
+#define CLUSTER_RX_OFF	CLUSTER_RXA_OFF
+#else
+#define CLUSTER_RX_OFF	CLUSTER_RXB_OFF
+#endif
+
+/* Relative to serdes unit base */
+#define REG_SERDES_STATUS	0x00
+#define SERDES_STATUS_EN	BIT(0)
+#define SERDES_STATUS_RST	BIT(1)
+#define REG_TX_SERDES_CONF	0x04
+#define REG_RX_SERDES_CONF	0x08
+#define SERDES_CONF_NCHANS	GENMASK(3, 0)
+#define SERDES_CONF_WIDTH_MASK	GENMASK(8, 4)
+#define SERDES_CONF_WIDTH_16BIT 0x40
+#define SERDES_CONF_WIDTH_20BIT 0x80
+#define SERDES_CONF_WIDTH_24BIT 0xc0
+#define SERDES_CONF_WIDTH_32BIT 0x100
+#define SERDES_CONF_BCLK_POL	0x400
+#define SERDES_CONF_LSB_FIRST	0x800
+#define SERDES_CONF_UNK1	BIT(12)
+#define SERDES_CONF_UNK2	BIT(13)
+#define SERDES_CONF_UNK3	BIT(14)
+#define SERDES_CONF_NO_DATA_FEEDBACK	BIT(15)
+#define SERDES_CONF_SYNC_SEL	GENMASK(18, 16)
+#define SERDES_CONF_SOME_RST	BIT(19)
+#define REG_TX_SERDES_BITSTART	0x08
+#define REG_RX_SERDES_BITSTART	0x0c
+#define REG_TX_SERDES_SLOTMASK	0x0c
+#define REG_RX_SERDES_SLOTMASK	0x10
+#define REG_RX_SERDES_PORT	0x04
+
+/* Relative to switch base */
+#define REG_DMA_ADAPTER_A(cl)	(0x8000 * (cl))
+#define REG_DMA_ADAPTER_B(cl)	(0x8000 * (cl) + 0x4000)
+#define DMA_ADAPTER_TX_LSB_PAD	GENMASK(4, 0)
+#define DMA_ADAPTER_TX_NCHANS	GENMASK(6, 5)
+#define DMA_ADAPTER_RX_MSB_PAD	GENMASK(12, 8)
+#define DMA_ADAPTER_RX_NCHANS	GENMASK(14, 13)
+#define DMA_ADAPTER_NCHANS	GENMASK(22, 20)
+
+#define SWITCH_STRIDE	0x8000
+#define CLUSTER_STRIDE	0x4000
+
+#define MAX_NCLUSTERS	6
+
+#define APPLE_MCA_FMTBITS (SNDRV_PCM_FMTBIT_S16_LE | \
+			   SNDRV_PCM_FMTBIT_S24_LE | \
+			   SNDRV_PCM_FMTBIT_S32_LE)
+
+struct mca_cluster {
+	int no;
+	__iomem void *base;
+	struct mca_data *host;
+	struct device *pd_dev;
+	struct clk *clk_parent;
+	struct dma_chan *dma_chans[SNDRV_PCM_STREAM_LAST + 1];
+
+	bool port_started[SNDRV_PCM_STREAM_LAST + 1];
+	int port_driver; /* The cluster driving this cluster's port */
+
+	bool clocks_in_use[SNDRV_PCM_STREAM_LAST + 1];
+	struct device_link *pd_link;
+
+	unsigned int bclk_ratio;
+
+	/* Masks etc. picked up via the set_tdm_slot method */
+	int tdm_slots;
+	int tdm_slot_width;
+	unsigned int tdm_tx_mask;
+	unsigned int tdm_rx_mask;
+};
+
+struct mca_data {
+	struct device *dev;
+
+	__iomem void *switch_base;
+
+	struct device *pd_dev;
+	struct reset_control *rstc;
+	struct device_link *pd_link;
+
+	int nclusters;
+	struct mca_cluster clusters[];
+};
+
+static void mca_modify(struct mca_cluster *cl, int regoffset, u32 mask, u32 val)
+{
+	__iomem void *ptr = cl->base + regoffset;
+	u32 newval;
+
+	newval = (val & mask) | (readl_relaxed(ptr) & ~mask);
+	writel_relaxed(newval, ptr);
+}
+
+/*
+ * Get the cluster of FE or BE DAI
+ */
+static struct mca_cluster *mca_dai_to_cluster(struct snd_soc_dai *dai)
+{
+	struct mca_data *mca = snd_soc_dai_get_drvdata(dai);
+	/*
+	 * FE DAIs are         0 ... nclusters - 1
+	 * BE DAIs are nclusters ... 2*nclusters - 1
+	 */
+	int cluster_no = dai->id % mca->nclusters;
+
+	return &mca->clusters[cluster_no];
+}
+
+/* called before PCM trigger */
+static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
+				 struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+	int serdes_conf =
+		serdes_unit + (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_RST);
+		mca_modify(cl, serdes_conf, SERDES_CONF_SOME_RST,
+			   SERDES_CONF_SOME_RST);
+		readl_relaxed(cl->base + serdes_conf);
+		mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
+		WARN_ON(readl_relaxed(cl->base + REG_SERDES_STATUS) &
+			SERDES_STATUS_RST);
+		break;
+	default:
+		break;
+	}
+}
+
+static int mca_fe_trigger(struct snd_pcm_substream *substream, int cmd,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_EN);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mca_fe_enable_clocks(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	int ret;
+
+	ret = clk_prepare_enable(cl->clk_parent);
+	if (ret) {
+		dev_err(mca->dev,
+			"cluster %d: unable to enable clock parent: %d\n",
+			cl->no, ret);
+		return ret;
+	}
+
+	/*
+	 * We can't power up the device earlier than this because
+	 * the power state driver would error out on seeing the device
+	 * as clock-gated.
+	 */
+	cl->pd_link = device_link_add(mca->dev, cl->pd_dev,
+				      DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					      DL_FLAG_RPM_ACTIVE);
+	if (!cl->pd_link) {
+		dev_err(mca->dev,
+			"cluster %d: unable to prop-up power domain\n", cl->no);
+		clk_disable_unprepare(cl->clk_parent);
+		return -EINVAL;
+	}
+
+	writel_relaxed(cl->no + 1, cl->base + REG_SYNCGEN_MCLK_SEL);
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN,
+		   SYNCGEN_STATUS_EN);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, STATUS_MCLK_EN);
+
+	return 0;
+}
+
+static void mca_fe_disable_clocks(struct mca_cluster *cl)
+{
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN, 0);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, 0);
+
+	device_link_del(cl->pd_link);
+	clk_disable_unprepare(cl->clk_parent);
+}
+
+static bool mca_fe_clocks_in_use(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *be_cl;
+	int stream, i;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		be_cl = &mca->clusters[i];
+
+		if (be_cl->port_driver != cl->no)
+			continue;
+
+		for_each_pcm_streams(stream)
+			if (be_cl->clocks_in_use[stream])
+				return true;
+	}
+	return false;
+}
+
+static int mca_be_prepare(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+	int ret;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+
+	/*
+	 * Typically the CODECs we are paired with will require clocks
+	 * to be present at time of unmute with the 'mute_stream' op
+	 * or at time of DAPM widget power-up. We need to enable clocks
+	 * here at the latest (frontend prepare would be too late).
+	 */
+	if (!mca_fe_clocks_in_use(fe_cl)) {
+		ret = mca_fe_enable_clocks(fe_cl);
+		if (ret < 0)
+			return ret;
+	}
+
+	cl->clocks_in_use[substream->stream] = true;
+
+	return 0;
+}
+
+static int mca_be_hw_free(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+	if (!mca_fe_clocks_in_use(fe_cl))
+		return 0; /* Nothing to do */
+
+	cl->clocks_in_use[substream->stream] = false;
+
+	if (!mca_fe_clocks_in_use(fe_cl))
+		mca_fe_disable_clocks(fe_cl);
+
+	return 0;
+}
+
+static unsigned int mca_crop_mask(unsigned int mask, int nchans)
+{
+	while (hweight32(mask) > nchans)
+		mask &= ~(1 << __fls(mask));
+
+	return mask;
+}
+
+static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
+				unsigned int mask, int slots, int nchans,
+				int slot_width, bool is_tx, int port)
+{
+	__iomem void *serdes_base = cl->base + serdes_unit;
+	u32 serdes_conf, serdes_conf_mask;
+
+	serdes_conf_mask = SERDES_CONF_WIDTH_MASK | SERDES_CONF_NCHANS;
+	serdes_conf = FIELD_PREP(SERDES_CONF_NCHANS, max(slots, 1) - 1);
+	switch (slot_width) {
+	case 16:
+		serdes_conf |= SERDES_CONF_WIDTH_16BIT;
+		break;
+	case 20:
+		serdes_conf |= SERDES_CONF_WIDTH_20BIT;
+		break;
+	case 24:
+		serdes_conf |= SERDES_CONF_WIDTH_24BIT;
+		break;
+	case 32:
+		serdes_conf |= SERDES_CONF_WIDTH_32BIT;
+		break;
+	default:
+		goto err;
+	}
+
+	serdes_conf_mask |= SERDES_CONF_SYNC_SEL;
+	serdes_conf |= FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1);
+
+	if (is_tx) {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_UNK3;
+	} else {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3 |
+				    SERDES_CONF_NO_DATA_FEEDBACK;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_NO_DATA_FEEDBACK;
+	}
+
+	mca_modify(cl,
+		   serdes_unit +
+			   (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF),
+		   serdes_conf_mask, serdes_conf);
+
+	if (is_tx) {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x8);
+		writel_relaxed(~((u32)mask),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0xc);
+	} else {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_RX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_RX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(1 << port,
+			       serdes_base + REG_RX_SERDES_PORT);
+	}
+
+	return 0;
+
+err:
+	dev_err(cl->host->dev,
+		"unsupported SERDES configuration requested (mask=0x%x slots=%d slot_width=%d)\n",
+		mask, slots, slot_width);
+	return -EINVAL;
+}
+
+static int mca_fe_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+			       unsigned int rx_mask, int slots, int slot_width)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->tdm_slots = slots;
+	cl->tdm_slot_width = slot_width;
+	cl->tdm_tx_mask = tx_mask;
+	cl->tdm_rx_mask = rx_mask;
+
+	return 0;
+}
+
+static int mca_fe_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	bool fpol_inv = false;
+	u32 serdes_conf = 0;
+	u32 bitstart;
+
+	if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) !=
+	    SND_SOC_DAIFMT_BP_FP)
+		goto err;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		fpol_inv = 0;
+		bitstart = 1;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		fpol_inv = 1;
+		bitstart = 0;
+		break;
+	default:
+		goto err;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_IF:
+	case SND_SOC_DAIFMT_IB_IF:
+		fpol_inv ^= 1;
+		break;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+	case SND_SOC_DAIFMT_NB_IF:
+		serdes_conf |= SERDES_CONF_BCLK_POL;
+		break;
+	}
+
+	if (!fpol_inv)
+		goto err;
+
+	mca_modify(cl, CLUSTER_TX_OFF + REG_TX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	mca_modify(cl, CLUSTER_RX_OFF + REG_RX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_TX_OFF + REG_TX_SERDES_BITSTART);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_RX_OFF + REG_RX_SERDES_BITSTART);
+
+	return 0;
+
+err:
+	dev_err(mca->dev, "unsupported DAI format (0x%x) requested\n", fmt);
+	return -EINVAL;
+}
+
+static int mca_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->bclk_ratio = ratio;
+
+	return 0;
+}
+
+static int mca_fe_get_port(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *be;
+	struct snd_soc_dpcm *dpcm;
+
+	be = NULL;
+	for_each_dpcm_be(fe, substream->stream, dpcm) {
+		be = dpcm->be;
+		break;
+	}
+
+	if (!be)
+		return -EINVAL;
+
+	return mca_dai_to_cluster(asoc_rtd_to_cpu(be, 0))->no;
+}
+
+static int mca_fe_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct device *dev = mca->dev;
+	unsigned int samp_rate = params_rate(params);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	bool refine_tdm = false;
+	unsigned long bclk_ratio;
+	unsigned int tdm_slots, tdm_slot_width, tdm_mask;
+	u32 regval, pad;
+	int ret, port, nchans_ceiled;
+
+	if (!cl->tdm_slot_width) {
+		/*
+		 * We were not given TDM settings from above, set initial
+		 * guesses which will later be refined.
+		 */
+		tdm_slot_width = params_width(params);
+		tdm_slots = params_channels(params);
+		refine_tdm = true;
+	} else {
+		tdm_slot_width = cl->tdm_slot_width;
+		tdm_slots = cl->tdm_slots;
+		tdm_mask = is_tx ? cl->tdm_tx_mask : cl->tdm_rx_mask;
+	}
+
+	if (cl->bclk_ratio)
+		bclk_ratio = cl->bclk_ratio;
+	else
+		bclk_ratio = tdm_slot_width * tdm_slots;
+
+	if (refine_tdm) {
+		int nchannels = params_channels(params);
+
+		if (nchannels > 2) {
+			dev_err(dev, "missing TDM for stream with two or more channels\n");
+			return -EINVAL;
+		}
+
+		if ((bclk_ratio % nchannels) != 0) {
+			dev_err(dev, "BCLK ratio (%ld) not divisible by no. of channels (%d)\n",
+				bclk_ratio, nchannels);
+			return -EINVAL;
+		}
+
+		tdm_slot_width = bclk_ratio / nchannels;
+
+		if (tdm_slot_width > 32 && nchannels == 1)
+			tdm_slot_width = 32;
+
+		if (tdm_slot_width < params_width(params)) {
+			dev_err(dev, "TDM slots too narrow (tdm=%d params=%d)\n",
+				tdm_slot_width, params_width(params));
+			return -EINVAL;
+		}
+
+		tdm_mask = (1 << tdm_slots) - 1;
+	}
+
+	port = mca_fe_get_port(substream);
+	if (port < 0)
+		return port;
+
+	ret = mca_configure_serdes(cl, is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF,
+				   tdm_mask, tdm_slots, params_channels(params),
+				   tdm_slot_width, is_tx, port);
+	if (ret)
+		return ret;
+
+	pad = 32 - params_width(params);
+
+	/*
+	 * TODO: Here the register semantics aren't clear.
+	 */
+	nchans_ceiled = min_t(int, params_channels(params), 4);
+	regval = FIELD_PREP(DMA_ADAPTER_NCHANS, nchans_ceiled) |
+		 FIELD_PREP(DMA_ADAPTER_TX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_RX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_TX_LSB_PAD, pad) |
+		 FIELD_PREP(DMA_ADAPTER_RX_MSB_PAD, pad);
+
+#ifndef USE_RXB_FOR_CAPTURE
+	writel_relaxed(regval, mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+#else
+	if (is_tx)
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+	else
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_B(cl->no));
+#endif
+
+	if (!mca_fe_clocks_in_use(cl)) {
+		/*
+		 * Set up FSYNC duty cycle as even as possible.
+		 */
+		writel_relaxed((bclk_ratio / 2) - 1,
+			       cl->base + REG_SYNCGEN_HI_PERIOD);
+		writel_relaxed(((bclk_ratio + 1) / 2) - 1,
+			       cl->base + REG_SYNCGEN_LO_PERIOD);
+		writel_relaxed(FIELD_PREP(MCLK_CONF_DIV, 0x1),
+			       cl->base + REG_MCLK_CONF);
+
+		ret = clk_set_rate(cl->clk_parent, bclk_ratio * samp_rate);
+		if (ret) {
+			dev_err(mca->dev, "cluster %d: unable to set clock parent: %d\n",
+				cl->no, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops mca_fe_ops = {
+	.set_fmt = mca_fe_set_fmt,
+	.set_bclk_ratio = mca_set_bclk_ratio,
+	.set_tdm_slot = mca_fe_set_tdm_slot,
+	.hw_params = mca_fe_hw_params,
+	.trigger = mca_fe_trigger,
+};
+
+static bool mca_be_started(struct mca_cluster *cl)
+{
+	int stream;
+
+	for_each_pcm_streams(stream)
+		if (cl->port_started[stream])
+			return true;
+	return false;
+}
+
+static int mca_be_startup(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *be = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *fe;
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_cluster *fe_cl;
+	struct mca_data *mca = cl->host;
+	struct snd_soc_dpcm *dpcm;
+
+	fe = NULL;
+
+	for_each_dpcm_fe(be, substream->stream, dpcm) {
+		if (fe && dpcm->fe != fe) {
+			dev_err(mca->dev, "many FE per one BE unsupported\n");
+			return -EINVAL;
+		}
+
+		fe = dpcm->fe;
+	}
+
+	if (!fe)
+		return -EINVAL;
+
+	fe_cl = mca_dai_to_cluster(asoc_rtd_to_cpu(fe, 0));
+
+	if (mca_be_started(cl)) {
+		/*
+		 * Port is already started in the other direction.
+		 * Make sure there isn't a conflict with another cluster
+		 * driving the port.
+		 */
+		if (cl->port_driver != fe_cl->no)
+			return -EINVAL;
+
+		cl->port_started[substream->stream] = true;
+		return 0;
+	}
+
+	writel_relaxed(PORT_ENABLES_CLOCKS | PORT_ENABLES_TX_DATA,
+		       cl->base + REG_PORT_ENABLES);
+	writel_relaxed(FIELD_PREP(PORT_CLOCK_SEL, fe_cl->no + 1),
+		       cl->base + REG_PORT_CLOCK_SEL);
+	writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no),
+		       cl->base + REG_PORT_DATA_SEL);
+	cl->port_driver = fe_cl->no;
+	cl->port_started[substream->stream] = true;
+
+	return 0;
+}
+
+static void mca_be_shutdown(struct snd_pcm_substream *substream,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->port_started[substream->stream] = false;
+
+	if (!mca_be_started(cl)) {
+		/*
+		 * Were we the last direction to shutdown?
+		 * Turn off the lights.
+		 */
+		writel_relaxed(0, cl->base + REG_PORT_ENABLES);
+		writel_relaxed(0, cl->base + REG_PORT_DATA_SEL);
+		cl->port_driver = -1;
+	}
+}
+
+static const struct snd_soc_dai_ops mca_be_ops = {
+	.prepare = mca_be_prepare,
+	.hw_free = mca_be_hw_free,
+	.startup = mca_be_startup,
+	.shutdown = mca_be_shutdown,
+};
+
+static int mca_set_runtime_hwparams(struct snd_soc_component *component,
+				    struct snd_pcm_substream *substream,
+				    struct dma_chan *chan)
+{
+	struct device *dma_dev = chan->device->dev;
+	struct snd_dmaengine_dai_dma_data dma_data = {};
+	int ret;
+
+	struct snd_pcm_hardware hw;
+
+	memset(&hw, 0, sizeof(hw));
+
+	hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+		  SNDRV_PCM_INFO_INTERLEAVED;
+	hw.periods_min = 2;
+	hw.periods_max = UINT_MAX;
+	hw.period_bytes_min = 256;
+	hw.period_bytes_max = dma_get_max_seg_size(dma_dev);
+	hw.buffer_bytes_max = SIZE_MAX;
+	hw.fifo_size = 16;
+
+	ret = snd_dmaengine_pcm_refine_runtime_hwparams(substream, &dma_data,
+							&hw, chan);
+
+	if (ret)
+		return ret;
+
+	return snd_soc_set_runtime_hwparams(substream, &hw);
+}
+
+static int mca_pcm_open(struct snd_soc_component *component,
+			struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	struct dma_chan *chan = cl->dma_chans[substream->stream];
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	ret = mca_set_runtime_hwparams(component, substream, chan);
+	if (ret)
+		return ret;
+
+	return snd_dmaengine_pcm_open(substream, chan);
+}
+
+static int mca_hw_params(struct snd_soc_component *component,
+			 struct snd_pcm_substream *substream,
+			 struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
+	struct dma_slave_config slave_config;
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	memset(&slave_config, 0, sizeof(slave_config));
+	ret = snd_hwparams_to_dma_slave_config(substream, params,
+					       &slave_config);
+	if (ret < 0)
+		return ret;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		slave_config.dst_port_window_size =
+			min_t(u32, params_channels(params), 4);
+	else
+		slave_config.src_port_window_size =
+			min_t(u32, params_channels(params), 4);
+
+	return dmaengine_slave_config(chan, &slave_config);
+}
+
+static int mca_close(struct snd_soc_component *component,
+		     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	return snd_dmaengine_pcm_close(substream);
+}
+
+static int mca_trigger(struct snd_soc_component *component,
+		       struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	/*
+	 * Before we do the PCM trigger proper, insert an opportunity
+	 * to reset the frontend's SERDES.
+	 */
+	mca_fe_early_trigger(substream, cmd, asoc_rtd_to_cpu(rtd, 0));
+
+	return snd_dmaengine_pcm_trigger(substream, cmd);
+}
+
+static snd_pcm_uframes_t mca_pointer(struct snd_soc_component *component,
+				     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return -ENOTSUPP;
+
+	return snd_dmaengine_pcm_pointer(substream);
+}
+
+static int mca_pcm_new(struct snd_soc_component *component,
+		       struct snd_soc_pcm_runtime *rtd)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	unsigned int i;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	for_each_pcm_streams(i) {
+		struct snd_pcm_substream *substream =
+			rtd->pcm->streams[i].substream;
+		struct dma_chan *chan = cl->dma_chans[i];
+
+		if (!substream)
+			continue;
+
+		if (!chan) {
+			dev_err(component->dev, "missing DMA channel for stream %d on SERDES %d\n",
+				i, cl->no);
+			return -EINVAL;
+		}
+
+		snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV_IRAM,
+					   chan->device->dev, 512 * 1024 * 6,
+					   SIZE_MAX);
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_component_driver mca_component = {
+	.name = "apple-mca",
+	.open = mca_pcm_open,
+	.close = mca_close,
+	.hw_params = mca_hw_params,
+	.trigger = mca_trigger,
+	.pointer = mca_pointer,
+	.pcm_construct = mca_pcm_new,
+};
+
+static void apple_mca_release(struct mca_data *mca)
+{
+	int i, stream;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		struct mca_cluster *cl = &mca->clusters[i];
+
+		for_each_pcm_streams(stream) {
+			if (IS_ERR_OR_NULL(cl->dma_chans[stream]))
+				continue;
+
+			dma_release_channel(cl->dma_chans[stream]);
+		}
+
+		if (!IS_ERR_OR_NULL(cl->clk_parent))
+			clk_put(cl->clk_parent);
+
+		if (!IS_ERR_OR_NULL(cl->pd_dev))
+			dev_pm_domain_detach(cl->pd_dev, true);
+	}
+
+	if (mca->pd_link)
+		device_link_del(mca->pd_link);
+
+	if (!IS_ERR_OR_NULL(mca->pd_dev))
+		dev_pm_domain_detach(mca->pd_dev, true);
+
+	reset_control_assert(mca->rstc);
+}
+
+static int apple_mca_probe(struct platform_device *pdev)
+{
+	struct mca_data *mca;
+	struct mca_cluster *clusters;
+	struct snd_soc_dai_driver *dai_drivers;
+	struct resource *res;
+	void __iomem *base;
+	int nclusters;
+	int ret, i;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	if (resource_size(res) < CLUSTER_STRIDE)
+		return -EINVAL;
+	nclusters = (resource_size(res) - CLUSTER_STRIDE) / CLUSTER_STRIDE + 1;
+
+	mca = devm_kzalloc(&pdev->dev, struct_size(mca, clusters, nclusters),
+			   GFP_KERNEL);
+	if (!mca)
+		return -ENOMEM;
+	mca->dev = &pdev->dev;
+	mca->nclusters = nclusters;
+	platform_set_drvdata(pdev, mca);
+	clusters = mca->clusters;
+
+	mca->switch_base =
+		devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(mca->switch_base))
+		return PTR_ERR(mca->switch_base);
+
+	mca->rstc = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
+	if (IS_ERR(mca->rstc))
+		return PTR_ERR(mca->rstc);
+
+	dai_drivers = devm_kzalloc(
+		&pdev->dev, sizeof(*dai_drivers) * 2 * nclusters, GFP_KERNEL);
+	if (!dai_drivers)
+		return -ENOMEM;
+
+	mca->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, 0);
+	if (IS_ERR(mca->pd_dev))
+		return -EINVAL;
+
+	mca->pd_link = device_link_add(&pdev->dev, mca->pd_dev,
+				       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					       DL_FLAG_RPM_ACTIVE);
+	if (!mca->pd_link) {
+		ret = -EINVAL;
+		/* Prevent an unbalanced reset assert */
+		mca->rstc = NULL;
+		goto err_release;
+	}
+
+	reset_control_deassert(mca->rstc);
+
+	for (i = 0; i < nclusters; i++) {
+		struct mca_cluster *cl = &clusters[i];
+		struct snd_soc_dai_driver *fe =
+			&dai_drivers[mca->nclusters + i];
+		struct snd_soc_dai_driver *be = &dai_drivers[i];
+		int stream;
+
+		cl->host = mca;
+		cl->no = i;
+		cl->base = base + CLUSTER_STRIDE * i;
+		cl->port_driver = -1;
+		cl->clk_parent = of_clk_get(pdev->dev.of_node, i);
+		if (IS_ERR(cl->clk_parent)) {
+			dev_err(&pdev->dev, "unable to obtain clock %d: %ld\n",
+				i, PTR_ERR(cl->clk_parent));
+			ret = PTR_ERR(cl->clk_parent);
+			goto err_release;
+		}
+		cl->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, i + 1);
+		if (IS_ERR(cl->pd_dev)) {
+			dev_err(&pdev->dev,
+				"unable to obtain cluster %d PD: %ld\n", i,
+				PTR_ERR(cl->pd_dev));
+			ret = PTR_ERR(cl->pd_dev);
+			goto err_release;
+		}
+
+		for_each_pcm_streams(stream) {
+			struct dma_chan *chan;
+			bool is_tx = (stream == SNDRV_PCM_STREAM_PLAYBACK);
+#ifndef USE_RXB_FOR_CAPTURE
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%da",
+						    i);
+#else
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%db",
+						    i);
+#endif
+
+			chan = of_dma_request_slave_channel(pdev->dev.of_node,
+							    name);
+			if (IS_ERR(chan)) {
+				if (PTR_ERR(chan) != -EPROBE_DEFER)
+					dev_err(&pdev->dev,
+						"no %s DMA channel: %ld\n",
+						name, PTR_ERR(chan));
+
+				ret = PTR_ERR(chan);
+				goto err_release;
+			}
+
+			cl->dma_chans[stream] = chan;
+		}
+
+		fe->id = i;
+		fe->name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-pcm-%d", i);
+		if (!fe->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		fe->ops = &mca_fe_ops;
+		fe->playback.channels_min = 1;
+		fe->playback.channels_max = 32;
+		fe->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->playback.formats = APPLE_MCA_FMTBITS;
+		fe->capture.channels_min = 1;
+		fe->capture.channels_max = 32;
+		fe->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->capture.formats = APPLE_MCA_FMTBITS;
+		fe->symmetric_rate = 1;
+
+		fe->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d TX", i);
+		fe->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d RX", i);
+
+		if (!fe->playback.stream_name || !fe->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+
+		be->id = i + nclusters;
+		be->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-i2s-%d", i);
+		if (!be->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		be->ops = &mca_be_ops;
+		be->playback.channels_min = 1;
+		be->playback.channels_max = 32;
+		be->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		be->playback.formats = APPLE_MCA_FMTBITS;
+		be->capture.channels_min = 1;
+		be->capture.channels_max = 32;
+		be->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		be->capture.formats = APPLE_MCA_FMTBITS;
+
+		be->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d TX", i);
+		be->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d RX", i);
+		if (!be->playback.stream_name || !be->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+	}
+
+	ret = devm_snd_soc_register_component(&pdev->dev, &mca_component,
+					      dai_drivers, nclusters * 2);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to register ASoC component: %d\n",
+			ret);
+		goto err_release;
+	}
+
+	return 0;
+
+err_release:
+	apple_mca_release(mca);
+	return ret;
+}
+
+static int apple_mca_remove(struct platform_device *pdev)
+{
+	struct mca_data *mca = platform_get_drvdata(pdev);
+
+	apple_mca_release(mca);
+	return 0;
+}
+
+static const struct of_device_id apple_mca_of_match[] = {
+	{ .compatible = "apple,mca", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, apple_mca_of_match);
+
+static struct platform_driver apple_mca_driver = {
+	.driver = {
+		.name = "apple-mca",
+		.of_match_table = apple_mca_of_match,
+	},
+	.probe = apple_mca_probe,
+	.remove = apple_mca_remove,
+};
+module_platform_driver(apple_mca_driver);
+
+MODULE_AUTHOR("Martin Povišer <povik+lin@cutebit.org>");
+MODULE_DESCRIPTION("ASoC Apple MCA driver");
+MODULE_LICENSE("GPL");
-- 
2.33.0


^ permalink raw reply related	[relevance 5%]

* [PATCH v3 3/4] ASoC: apple: mca: Start new platform driver
@ 2022-08-24 16:07  5%   ` Martin Povišer
  0 siblings, 0 replies; 200+ results
From: Martin Povišer @ 2022-08-24 16:07 UTC (permalink / raw)
  To: Martin Povišer, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Hector Martin, Sven Peter, Philipp Zabel
  Cc: devicetree, alsa-devel, asahi, Alyssa Rosenzweig, linux-kernel

Add ASoC platform driver for the MCA peripheral found on Apple M1 and
other chips.

Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
---
 MAINTAINERS              |    8 +
 sound/soc/Kconfig        |    1 +
 sound/soc/Makefile       |    1 +
 sound/soc/apple/Kconfig  |    9 +
 sound/soc/apple/Makefile |    3 +
 sound/soc/apple/mca.c    | 1148 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 1170 insertions(+)
 create mode 100644 sound/soc/apple/Kconfig
 create mode 100644 sound/soc/apple/Makefile
 create mode 100644 sound/soc/apple/mca.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 8a5012ba6ff9..5f91a6b62f2f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1899,6 +1899,14 @@ F:	include/dt-bindings/pinctrl/apple.h
 F:	include/linux/apple-mailbox.h
 F:	include/linux/soc/apple/*
 
+ARM/APPLE MACHINE SOUND DRIVERS
+M:	Martin Povišer <povik+lin@cutebit.org>
+L:	asahi@lists.linux.dev
+L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/sound/apple,*
+F:	drivers/sound/apple/*
+
 ARM/ARTPEC MACHINE SUPPORT
 M:	Jesper Nilsson <jesper.nilsson@axis.com>
 M:	Lars Persson <lars.persson@axis.com>
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 7d4747b6bab2..848fbae26c3b 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -68,6 +68,7 @@ config SND_SOC_ACPI
 # All the supported SoCs
 source "sound/soc/adi/Kconfig"
 source "sound/soc/amd/Kconfig"
+source "sound/soc/apple/Kconfig"
 source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
 source "sound/soc/bcm/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 453181ef6c94..507eaed1d6a1 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SND_SOC_ACPI) += snd-soc-acpi.o
 obj-$(CONFIG_SND_SOC)	+= snd-soc-core.o
 obj-$(CONFIG_SND_SOC)	+= codecs/
 obj-$(CONFIG_SND_SOC)	+= generic/
+obj-$(CONFIG_SND_SOC)	+= apple/
 obj-$(CONFIG_SND_SOC)	+= adi/
 obj-$(CONFIG_SND_SOC)	+= amd/
 obj-$(CONFIG_SND_SOC)	+= atmel/
diff --git a/sound/soc/apple/Kconfig b/sound/soc/apple/Kconfig
new file mode 100644
index 000000000000..0ba955657e98
--- /dev/null
+++ b/sound/soc/apple/Kconfig
@@ -0,0 +1,9 @@
+config SND_SOC_APPLE_MCA
+	tristate "Apple Silicon MCA driver"
+	depends on ARCH_APPLE || COMPILE_TEST
+	select SND_DMAENGINE_PCM
+	select COMMON_CLK
+	default ARCH_APPLE
+	help
+	  This option enables an ASoC platform driver for MCA peripherals found
+	  on Apple Silicon SoCs.
diff --git a/sound/soc/apple/Makefile b/sound/soc/apple/Makefile
new file mode 100644
index 000000000000..7a30bf452817
--- /dev/null
+++ b/sound/soc/apple/Makefile
@@ -0,0 +1,3 @@
+snd-soc-apple-mca-objs	:= mca.o
+
+obj-$(CONFIG_SND_SOC_APPLE_MCA)	+= snd-soc-apple-mca.o
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
new file mode 100644
index 000000000000..807b85469408
--- /dev/null
+++ b/sound/soc/apple/mca.c
@@ -0,0 +1,1148 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Apple SoCs MCA driver
+//
+// Copyright (C) The Asahi Linux Contributors
+//
+// The MCA peripheral is made up of a number of identical units called clusters.
+// Each cluster has its separate clock parent, SYNC signal generator, carries
+// four SERDES units and has a dedicated I2S port on the SoC's periphery.
+//
+// The clusters can operate independently, or can be combined together in a
+// configurable manner. We mostly treat them as self-contained independent
+// units and don't configure any cross-cluster connections except for the I2S
+// ports. The I2S ports can be routed to any of the clusters (irrespective
+// of their native cluster). We map this onto ASoC's (DPCM) notion of backend
+// and frontend DAIs. The 'cluster guts' are frontends which are dynamically
+// routed to backend I2S ports.
+//
+// DAI references in devicetree are resolved to backends. The routing between
+// frontends and backends is determined by the machine driver in the DAPM paths
+// it supplies.
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_clk.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+
+#define USE_RXB_FOR_CAPTURE
+
+/* Relative to cluster base */
+#define REG_STATUS		0x0
+#define STATUS_MCLK_EN		BIT(0)
+#define REG_MCLK_CONF		0x4
+#define MCLK_CONF_DIV		GENMASK(11, 8)
+
+#define REG_SYNCGEN_STATUS	0x100
+#define SYNCGEN_STATUS_EN	BIT(0)
+#define REG_SYNCGEN_MCLK_SEL	0x104
+#define SYNCGEN_MCLK_SEL	GENMASK(3, 0)
+#define REG_SYNCGEN_HI_PERIOD	0x108
+#define REG_SYNCGEN_LO_PERIOD	0x10c
+
+#define REG_PORT_ENABLES	0x600
+#define PORT_ENABLES_CLOCKS	GENMASK(2, 1)
+#define PORT_ENABLES_TX_DATA	BIT(3)
+#define REG_PORT_CLOCK_SEL	0x604
+#define PORT_CLOCK_SEL		GENMASK(11, 8)
+#define REG_PORT_DATA_SEL	0x608
+#define PORT_DATA_SEL_TXA(cl)	(1 << ((cl)*2))
+#define PORT_DATA_SEL_TXB(cl)	(2 << ((cl)*2))
+
+#define REG_INTSTATE		0x700
+#define REG_INTMASK		0x704
+
+/* Bases of serdes units (relative to cluster) */
+#define CLUSTER_RXA_OFF	0x200
+#define CLUSTER_TXA_OFF	0x300
+#define CLUSTER_RXB_OFF	0x400
+#define CLUSTER_TXB_OFF	0x500
+
+#define CLUSTER_TX_OFF	CLUSTER_TXA_OFF
+
+#ifndef USE_RXB_FOR_CAPTURE
+#define CLUSTER_RX_OFF	CLUSTER_RXA_OFF
+#else
+#define CLUSTER_RX_OFF	CLUSTER_RXB_OFF
+#endif
+
+/* Relative to serdes unit base */
+#define REG_SERDES_STATUS	0x00
+#define SERDES_STATUS_EN	BIT(0)
+#define SERDES_STATUS_RST	BIT(1)
+#define REG_TX_SERDES_CONF	0x04
+#define REG_RX_SERDES_CONF	0x08
+#define SERDES_CONF_NCHANS	GENMASK(3, 0)
+#define SERDES_CONF_WIDTH_MASK	GENMASK(8, 4)
+#define SERDES_CONF_WIDTH_16BIT 0x40
+#define SERDES_CONF_WIDTH_20BIT 0x80
+#define SERDES_CONF_WIDTH_24BIT 0xc0
+#define SERDES_CONF_WIDTH_32BIT 0x100
+#define SERDES_CONF_BCLK_POL	0x400
+#define SERDES_CONF_LSB_FIRST	0x800
+#define SERDES_CONF_UNK1	BIT(12)
+#define SERDES_CONF_UNK2	BIT(13)
+#define SERDES_CONF_UNK3	BIT(14)
+#define SERDES_CONF_NO_DATA_FEEDBACK	BIT(15)
+#define SERDES_CONF_SYNC_SEL	GENMASK(18, 16)
+#define SERDES_CONF_SOME_RST	BIT(19)
+#define REG_TX_SERDES_BITSTART	0x08
+#define REG_RX_SERDES_BITSTART	0x0c
+#define REG_TX_SERDES_SLOTMASK	0x0c
+#define REG_RX_SERDES_SLOTMASK	0x10
+#define REG_RX_SERDES_PORT	0x04
+
+/* Relative to switch base */
+#define REG_DMA_ADAPTER_A(cl)	(0x8000 * (cl))
+#define REG_DMA_ADAPTER_B(cl)	(0x8000 * (cl) + 0x4000)
+#define DMA_ADAPTER_TX_LSB_PAD	GENMASK(4, 0)
+#define DMA_ADAPTER_TX_NCHANS	GENMASK(6, 5)
+#define DMA_ADAPTER_RX_MSB_PAD	GENMASK(12, 8)
+#define DMA_ADAPTER_RX_NCHANS	GENMASK(14, 13)
+#define DMA_ADAPTER_NCHANS	GENMASK(22, 20)
+
+#define SWITCH_STRIDE	0x8000
+#define CLUSTER_STRIDE	0x4000
+
+#define MAX_NCLUSTERS	6
+
+#define APPLE_MCA_FMTBITS (SNDRV_PCM_FMTBIT_S16_LE | \
+			   SNDRV_PCM_FMTBIT_S24_LE | \
+			   SNDRV_PCM_FMTBIT_S32_LE)
+
+struct mca_cluster {
+	int no;
+	__iomem void *base;
+	struct mca_data *host;
+	struct device *pd_dev;
+	struct clk *clk_parent;
+	struct dma_chan *dma_chans[SNDRV_PCM_STREAM_LAST + 1];
+
+	bool port_started[SNDRV_PCM_STREAM_LAST + 1];
+	int port_driver; /* The cluster driving this cluster's port */
+
+	bool clocks_in_use[SNDRV_PCM_STREAM_LAST + 1];
+	struct device_link *pd_link;
+
+	unsigned int bclk_ratio;
+
+	/* Masks etc. picked up via the set_tdm_slot method */
+	int tdm_slots;
+	int tdm_slot_width;
+	unsigned int tdm_tx_mask;
+	unsigned int tdm_rx_mask;
+};
+
+struct mca_data {
+	struct device *dev;
+
+	__iomem void *switch_base;
+
+	struct device *pd_dev;
+	struct reset_control *rstc;
+	struct device_link *pd_link;
+
+	int nclusters;
+	struct mca_cluster clusters[];
+};
+
+static void mca_modify(struct mca_cluster *cl, int regoffset, u32 mask, u32 val)
+{
+	__iomem void *ptr = cl->base + regoffset;
+	u32 newval;
+
+	newval = (val & mask) | (readl_relaxed(ptr) & ~mask);
+	writel_relaxed(newval, ptr);
+}
+
+/*
+ * Get the cluster of FE or BE DAI
+ */
+static struct mca_cluster *mca_dai_to_cluster(struct snd_soc_dai *dai)
+{
+	struct mca_data *mca = snd_soc_dai_get_drvdata(dai);
+	/*
+	 * FE DAIs are         0 ... nclusters - 1
+	 * BE DAIs are nclusters ... 2*nclusters - 1
+	 */
+	int cluster_no = dai->id % mca->nclusters;
+
+	return &mca->clusters[cluster_no];
+}
+
+/* called before PCM trigger */
+static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
+				 struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+	int serdes_conf =
+		serdes_unit + (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_RST);
+		mca_modify(cl, serdes_conf, SERDES_CONF_SOME_RST,
+			   SERDES_CONF_SOME_RST);
+		readl_relaxed(cl->base + serdes_conf);
+		mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
+		WARN_ON(readl_relaxed(cl->base + REG_SERDES_STATUS) &
+			SERDES_STATUS_RST);
+		break;
+	default:
+		break;
+	}
+}
+
+static int mca_fe_trigger(struct snd_pcm_substream *substream, int cmd,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_EN);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mca_fe_enable_clocks(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	int ret;
+
+	ret = clk_prepare_enable(cl->clk_parent);
+	if (ret) {
+		dev_err(mca->dev,
+			"cluster %d: unable to enable clock parent: %d\n",
+			cl->no, ret);
+		return ret;
+	}
+
+	/*
+	 * We can't power up the device earlier than this because
+	 * the power state driver would error out on seeing the device
+	 * as clock-gated.
+	 */
+	cl->pd_link = device_link_add(mca->dev, cl->pd_dev,
+				      DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					      DL_FLAG_RPM_ACTIVE);
+	if (!cl->pd_link) {
+		dev_err(mca->dev,
+			"cluster %d: unable to prop-up power domain\n", cl->no);
+		clk_disable_unprepare(cl->clk_parent);
+		return -EINVAL;
+	}
+
+	writel_relaxed(cl->no + 1, cl->base + REG_SYNCGEN_MCLK_SEL);
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN,
+		   SYNCGEN_STATUS_EN);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, STATUS_MCLK_EN);
+
+	return 0;
+}
+
+static void mca_fe_disable_clocks(struct mca_cluster *cl)
+{
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN, 0);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, 0);
+
+	device_link_del(cl->pd_link);
+	clk_disable_unprepare(cl->clk_parent);
+}
+
+static bool mca_fe_clocks_in_use(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *be_cl;
+	int stream, i;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		be_cl = &mca->clusters[i];
+
+		if (be_cl->port_driver != cl->no)
+			continue;
+
+		for_each_pcm_streams(stream)
+			if (be_cl->clocks_in_use[stream])
+				return true;
+	}
+	return false;
+}
+
+static int mca_be_prepare(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+	int ret;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+
+	/*
+	 * Typically the CODECs we are paired with will require clocks
+	 * to be present at time of unmute with the 'mute_stream' op
+	 * or at time of DAPM widget power-up. We need to enable clocks
+	 * here at the latest (frontend prepare would be too late).
+	 */
+	if (!mca_fe_clocks_in_use(fe_cl)) {
+		ret = mca_fe_enable_clocks(fe_cl);
+		if (ret < 0)
+			return ret;
+	}
+
+	cl->clocks_in_use[substream->stream] = true;
+
+	return 0;
+}
+
+static int mca_be_hw_free(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+	if (!mca_fe_clocks_in_use(fe_cl))
+		return 0; /* Nothing to do */
+
+	cl->clocks_in_use[substream->stream] = false;
+
+	if (!mca_fe_clocks_in_use(fe_cl))
+		mca_fe_disable_clocks(fe_cl);
+
+	return 0;
+}
+
+static unsigned int mca_crop_mask(unsigned int mask, int nchans)
+{
+	while (hweight32(mask) > nchans)
+		mask &= ~(1 << __fls(mask));
+
+	return mask;
+}
+
+static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
+				unsigned int mask, int slots, int nchans,
+				int slot_width, bool is_tx, int port)
+{
+	__iomem void *serdes_base = cl->base + serdes_unit;
+	u32 serdes_conf, serdes_conf_mask;
+
+	serdes_conf_mask = SERDES_CONF_WIDTH_MASK | SERDES_CONF_NCHANS;
+	serdes_conf = FIELD_PREP(SERDES_CONF_NCHANS, max(slots, 1) - 1);
+	switch (slot_width) {
+	case 16:
+		serdes_conf |= SERDES_CONF_WIDTH_16BIT;
+		break;
+	case 20:
+		serdes_conf |= SERDES_CONF_WIDTH_20BIT;
+		break;
+	case 24:
+		serdes_conf |= SERDES_CONF_WIDTH_24BIT;
+		break;
+	case 32:
+		serdes_conf |= SERDES_CONF_WIDTH_32BIT;
+		break;
+	default:
+		goto err;
+	}
+
+	serdes_conf_mask |= SERDES_CONF_SYNC_SEL;
+	serdes_conf |= FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1);
+
+	if (is_tx) {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_UNK3;
+	} else {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3 |
+				    SERDES_CONF_NO_DATA_FEEDBACK;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_NO_DATA_FEEDBACK;
+	}
+
+	mca_modify(cl,
+		   serdes_unit +
+			   (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF),
+		   serdes_conf_mask, serdes_conf);
+
+	if (is_tx) {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x8);
+		writel_relaxed(~((u32)mask),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0xc);
+	} else {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_RX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_RX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(1 << port,
+			       serdes_base + REG_RX_SERDES_PORT);
+	}
+
+	return 0;
+
+err:
+	dev_err(cl->host->dev,
+		"unsupported SERDES configuration requested (mask=0x%x slots=%d slot_width=%d)\n",
+		mask, slots, slot_width);
+	return -EINVAL;
+}
+
+static int mca_fe_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+			       unsigned int rx_mask, int slots, int slot_width)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->tdm_slots = slots;
+	cl->tdm_slot_width = slot_width;
+	cl->tdm_tx_mask = tx_mask;
+	cl->tdm_rx_mask = rx_mask;
+
+	return 0;
+}
+
+static int mca_fe_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	bool fpol_inv = false;
+	u32 serdes_conf = 0;
+	u32 bitstart;
+
+	if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) !=
+	    SND_SOC_DAIFMT_BP_FP)
+		goto err;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		fpol_inv = 0;
+		bitstart = 1;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		fpol_inv = 1;
+		bitstart = 0;
+		break;
+	default:
+		goto err;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_IF:
+	case SND_SOC_DAIFMT_IB_IF:
+		fpol_inv ^= 1;
+		break;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+	case SND_SOC_DAIFMT_NB_IF:
+		serdes_conf |= SERDES_CONF_BCLK_POL;
+		break;
+	}
+
+	if (!fpol_inv)
+		goto err;
+
+	mca_modify(cl, CLUSTER_TX_OFF + REG_TX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	mca_modify(cl, CLUSTER_RX_OFF + REG_RX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_TX_OFF + REG_TX_SERDES_BITSTART);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_RX_OFF + REG_RX_SERDES_BITSTART);
+
+	return 0;
+
+err:
+	dev_err(mca->dev, "unsupported DAI format (0x%x) requested\n", fmt);
+	return -EINVAL;
+}
+
+static int mca_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->bclk_ratio = ratio;
+
+	return 0;
+}
+
+static int mca_fe_get_port(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *be;
+	struct snd_soc_dpcm *dpcm;
+
+	be = NULL;
+	for_each_dpcm_be(fe, substream->stream, dpcm) {
+		be = dpcm->be;
+		break;
+	}
+
+	if (!be)
+		return -EINVAL;
+
+	return mca_dai_to_cluster(asoc_rtd_to_cpu(be, 0))->no;
+}
+
+static int mca_fe_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct device *dev = mca->dev;
+	unsigned int samp_rate = params_rate(params);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	bool refine_tdm = false;
+	unsigned long bclk_ratio;
+	unsigned int tdm_slots, tdm_slot_width, tdm_mask;
+	u32 regval, pad;
+	int ret, port, nchans_ceiled;
+
+	if (!cl->tdm_slot_width) {
+		/*
+		 * We were not given TDM settings from above, set initial
+		 * guesses which will later be refined.
+		 */
+		tdm_slot_width = params_width(params);
+		tdm_slots = params_channels(params);
+		refine_tdm = true;
+	} else {
+		tdm_slot_width = cl->tdm_slot_width;
+		tdm_slots = cl->tdm_slots;
+		tdm_mask = is_tx ? cl->tdm_tx_mask : cl->tdm_rx_mask;
+	}
+
+	if (cl->bclk_ratio)
+		bclk_ratio = cl->bclk_ratio;
+	else
+		bclk_ratio = tdm_slot_width * tdm_slots;
+
+	if (refine_tdm) {
+		int nchannels = params_channels(params);
+
+		if (nchannels > 2) {
+			dev_err(dev, "missing TDM for stream with two or more channels\n");
+			return -EINVAL;
+		}
+
+		if ((bclk_ratio % nchannels) != 0) {
+			dev_err(dev, "BCLK ratio (%ld) not divisible by no. of channels (%d)\n",
+				bclk_ratio, nchannels);
+			return -EINVAL;
+		}
+
+		tdm_slot_width = bclk_ratio / nchannels;
+
+		if (tdm_slot_width > 32 && nchannels == 1)
+			tdm_slot_width = 32;
+
+		if (tdm_slot_width < params_width(params)) {
+			dev_err(dev, "TDM slots too narrow (tdm=%d params=%d)\n",
+				tdm_slot_width, params_width(params));
+			return -EINVAL;
+		}
+
+		tdm_mask = (1 << tdm_slots) - 1;
+	}
+
+	port = mca_fe_get_port(substream);
+	if (port < 0)
+		return port;
+
+	ret = mca_configure_serdes(cl, is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF,
+				   tdm_mask, tdm_slots, params_channels(params),
+				   tdm_slot_width, is_tx, port);
+	if (ret)
+		return ret;
+
+	pad = 32 - params_width(params);
+
+	/*
+	 * TODO: Here the register semantics aren't clear.
+	 */
+	nchans_ceiled = min_t(int, params_channels(params), 4);
+	regval = FIELD_PREP(DMA_ADAPTER_NCHANS, nchans_ceiled) |
+		 FIELD_PREP(DMA_ADAPTER_TX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_RX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_TX_LSB_PAD, pad) |
+		 FIELD_PREP(DMA_ADAPTER_RX_MSB_PAD, pad);
+
+#ifndef USE_RXB_FOR_CAPTURE
+	writel_relaxed(regval, mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+#else
+	if (is_tx)
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+	else
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_B(cl->no));
+#endif
+
+	if (!mca_fe_clocks_in_use(cl)) {
+		/*
+		 * Set up FSYNC duty cycle as even as possible.
+		 */
+		writel_relaxed((bclk_ratio / 2) - 1,
+			       cl->base + REG_SYNCGEN_HI_PERIOD);
+		writel_relaxed(((bclk_ratio + 1) / 2) - 1,
+			       cl->base + REG_SYNCGEN_LO_PERIOD);
+		writel_relaxed(FIELD_PREP(MCLK_CONF_DIV, 0x1),
+			       cl->base + REG_MCLK_CONF);
+
+		ret = clk_set_rate(cl->clk_parent, bclk_ratio * samp_rate);
+		if (ret) {
+			dev_err(mca->dev, "cluster %d: unable to set clock parent: %d\n",
+				cl->no, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops mca_fe_ops = {
+	.set_fmt = mca_fe_set_fmt,
+	.set_bclk_ratio = mca_set_bclk_ratio,
+	.set_tdm_slot = mca_fe_set_tdm_slot,
+	.hw_params = mca_fe_hw_params,
+	.trigger = mca_fe_trigger,
+};
+
+static bool mca_be_started(struct mca_cluster *cl)
+{
+	int stream;
+
+	for_each_pcm_streams(stream)
+		if (cl->port_started[stream])
+			return true;
+	return false;
+}
+
+static int mca_be_startup(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *be = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *fe;
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_cluster *fe_cl;
+	struct mca_data *mca = cl->host;
+	struct snd_soc_dpcm *dpcm;
+
+	fe = NULL;
+
+	for_each_dpcm_fe(be, substream->stream, dpcm) {
+		if (fe && dpcm->fe != fe) {
+			dev_err(mca->dev, "many FE per one BE unsupported\n");
+			return -EINVAL;
+		}
+
+		fe = dpcm->fe;
+	}
+
+	if (!fe)
+		return -EINVAL;
+
+	fe_cl = mca_dai_to_cluster(asoc_rtd_to_cpu(fe, 0));
+
+	if (mca_be_started(cl)) {
+		/*
+		 * Port is already started in the other direction.
+		 * Make sure there isn't a conflict with another cluster
+		 * driving the port.
+		 */
+		if (cl->port_driver != fe_cl->no)
+			return -EINVAL;
+
+		cl->port_started[substream->stream] = true;
+		return 0;
+	}
+
+	writel_relaxed(PORT_ENABLES_CLOCKS | PORT_ENABLES_TX_DATA,
+		       cl->base + REG_PORT_ENABLES);
+	writel_relaxed(FIELD_PREP(PORT_CLOCK_SEL, fe_cl->no + 1),
+		       cl->base + REG_PORT_CLOCK_SEL);
+	writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no),
+		       cl->base + REG_PORT_DATA_SEL);
+	cl->port_driver = fe_cl->no;
+	cl->port_started[substream->stream] = true;
+
+	return 0;
+}
+
+static void mca_be_shutdown(struct snd_pcm_substream *substream,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->port_started[substream->stream] = false;
+
+	if (!mca_be_started(cl)) {
+		/*
+		 * Were we the last direction to shutdown?
+		 * Turn off the lights.
+		 */
+		writel_relaxed(0, cl->base + REG_PORT_ENABLES);
+		writel_relaxed(0, cl->base + REG_PORT_DATA_SEL);
+		cl->port_driver = -1;
+	}
+}
+
+static const struct snd_soc_dai_ops mca_be_ops = {
+	.prepare = mca_be_prepare,
+	.hw_free = mca_be_hw_free,
+	.startup = mca_be_startup,
+	.shutdown = mca_be_shutdown,
+};
+
+static int mca_set_runtime_hwparams(struct snd_soc_component *component,
+				    struct snd_pcm_substream *substream,
+				    struct dma_chan *chan)
+{
+	struct device *dma_dev = chan->device->dev;
+	struct snd_dmaengine_dai_dma_data dma_data = {};
+	int ret;
+
+	struct snd_pcm_hardware hw;
+
+	memset(&hw, 0, sizeof(hw));
+
+	hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+		  SNDRV_PCM_INFO_INTERLEAVED;
+	hw.periods_min = 2;
+	hw.periods_max = UINT_MAX;
+	hw.period_bytes_min = 256;
+	hw.period_bytes_max = dma_get_max_seg_size(dma_dev);
+	hw.buffer_bytes_max = SIZE_MAX;
+	hw.fifo_size = 16;
+
+	ret = snd_dmaengine_pcm_refine_runtime_hwparams(substream, &dma_data,
+							&hw, chan);
+
+	if (ret)
+		return ret;
+
+	return snd_soc_set_runtime_hwparams(substream, &hw);
+}
+
+static int mca_pcm_open(struct snd_soc_component *component,
+			struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	struct dma_chan *chan = cl->dma_chans[substream->stream];
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	ret = mca_set_runtime_hwparams(component, substream, chan);
+	if (ret)
+		return ret;
+
+	return snd_dmaengine_pcm_open(substream, chan);
+}
+
+static int mca_hw_params(struct snd_soc_component *component,
+			 struct snd_pcm_substream *substream,
+			 struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
+	struct dma_slave_config slave_config;
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	memset(&slave_config, 0, sizeof(slave_config));
+	ret = snd_hwparams_to_dma_slave_config(substream, params,
+					       &slave_config);
+	if (ret < 0)
+		return ret;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		slave_config.dst_port_window_size =
+			min_t(u32, params_channels(params), 4);
+	else
+		slave_config.src_port_window_size =
+			min_t(u32, params_channels(params), 4);
+
+	return dmaengine_slave_config(chan, &slave_config);
+}
+
+static int mca_close(struct snd_soc_component *component,
+		     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	return snd_dmaengine_pcm_close(substream);
+}
+
+static int mca_trigger(struct snd_soc_component *component,
+		       struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	/*
+	 * Before we do the PCM trigger proper, insert an opportunity
+	 * to reset the frontend's SERDES.
+	 */
+	mca_fe_early_trigger(substream, cmd, asoc_rtd_to_cpu(rtd, 0));
+
+	return snd_dmaengine_pcm_trigger(substream, cmd);
+}
+
+static snd_pcm_uframes_t mca_pointer(struct snd_soc_component *component,
+				     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return -ENOTSUPP;
+
+	return snd_dmaengine_pcm_pointer(substream);
+}
+
+static int mca_pcm_new(struct snd_soc_component *component,
+		       struct snd_soc_pcm_runtime *rtd)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	unsigned int i;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	for_each_pcm_streams(i) {
+		struct snd_pcm_substream *substream =
+			rtd->pcm->streams[i].substream;
+		struct dma_chan *chan = cl->dma_chans[i];
+
+		if (!substream)
+			continue;
+
+		if (!chan) {
+			dev_err(component->dev, "missing DMA channel for stream %d on SERDES %d\n",
+				i, cl->no);
+			return -EINVAL;
+		}
+
+		snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV_IRAM,
+					   chan->device->dev, 512 * 1024 * 6,
+					   SIZE_MAX);
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_component_driver mca_component = {
+	.name = "apple-mca",
+	.open = mca_pcm_open,
+	.close = mca_close,
+	.hw_params = mca_hw_params,
+	.trigger = mca_trigger,
+	.pointer = mca_pointer,
+	.pcm_construct = mca_pcm_new,
+};
+
+static void apple_mca_release(struct mca_data *mca)
+{
+	int i, stream;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		struct mca_cluster *cl = &mca->clusters[i];
+
+		for_each_pcm_streams(stream) {
+			if (IS_ERR_OR_NULL(cl->dma_chans[stream]))
+				continue;
+
+			dma_release_channel(cl->dma_chans[stream]);
+		}
+
+		if (!IS_ERR_OR_NULL(cl->clk_parent))
+			clk_put(cl->clk_parent);
+
+		if (!IS_ERR_OR_NULL(cl->pd_dev))
+			dev_pm_domain_detach(cl->pd_dev, true);
+	}
+
+	if (mca->pd_link)
+		device_link_del(mca->pd_link);
+
+	if (!IS_ERR_OR_NULL(mca->pd_dev))
+		dev_pm_domain_detach(mca->pd_dev, true);
+
+	reset_control_assert(mca->rstc);
+}
+
+static int apple_mca_probe(struct platform_device *pdev)
+{
+	struct mca_data *mca;
+	struct mca_cluster *clusters;
+	struct snd_soc_dai_driver *dai_drivers;
+	struct resource *res;
+	void __iomem *base;
+	int nclusters;
+	int ret, i;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	if (resource_size(res) < CLUSTER_STRIDE)
+		return -EINVAL;
+	nclusters = (resource_size(res) - CLUSTER_STRIDE) / CLUSTER_STRIDE + 1;
+
+	mca = devm_kzalloc(&pdev->dev, struct_size(mca, clusters, nclusters),
+			   GFP_KERNEL);
+	if (!mca)
+		return -ENOMEM;
+	mca->dev = &pdev->dev;
+	mca->nclusters = nclusters;
+	platform_set_drvdata(pdev, mca);
+	clusters = mca->clusters;
+
+	mca->switch_base =
+		devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(mca->switch_base))
+		return PTR_ERR(mca->switch_base);
+
+	mca->rstc = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
+	if (IS_ERR(mca->rstc))
+		return PTR_ERR(mca->rstc);
+
+	dai_drivers = devm_kzalloc(
+		&pdev->dev, sizeof(*dai_drivers) * 2 * nclusters, GFP_KERNEL);
+	if (!dai_drivers)
+		return -ENOMEM;
+
+	mca->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, 0);
+	if (IS_ERR(mca->pd_dev))
+		return -EINVAL;
+
+	mca->pd_link = device_link_add(&pdev->dev, mca->pd_dev,
+				       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					       DL_FLAG_RPM_ACTIVE);
+	if (!mca->pd_link) {
+		ret = -EINVAL;
+		/* Prevent an unbalanced reset assert */
+		mca->rstc = NULL;
+		goto err_release;
+	}
+
+	reset_control_deassert(mca->rstc);
+
+	for (i = 0; i < nclusters; i++) {
+		struct mca_cluster *cl = &clusters[i];
+		struct snd_soc_dai_driver *fe =
+			&dai_drivers[mca->nclusters + i];
+		struct snd_soc_dai_driver *be = &dai_drivers[i];
+		int stream;
+
+		cl->host = mca;
+		cl->no = i;
+		cl->base = base + CLUSTER_STRIDE * i;
+		cl->port_driver = -1;
+		cl->clk_parent = of_clk_get(pdev->dev.of_node, i);
+		if (IS_ERR(cl->clk_parent)) {
+			dev_err(&pdev->dev, "unable to obtain clock %d: %ld\n",
+				i, PTR_ERR(cl->clk_parent));
+			ret = PTR_ERR(cl->clk_parent);
+			goto err_release;
+		}
+		cl->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, i + 1);
+		if (IS_ERR(cl->pd_dev)) {
+			dev_err(&pdev->dev,
+				"unable to obtain cluster %d PD: %ld\n", i,
+				PTR_ERR(cl->pd_dev));
+			ret = PTR_ERR(cl->pd_dev);
+			goto err_release;
+		}
+
+		for_each_pcm_streams(stream) {
+			struct dma_chan *chan;
+			bool is_tx = (stream == SNDRV_PCM_STREAM_PLAYBACK);
+#ifndef USE_RXB_FOR_CAPTURE
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%da",
+						    i);
+#else
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%db",
+						    i);
+#endif
+
+			chan = of_dma_request_slave_channel(pdev->dev.of_node,
+							    name);
+			if (IS_ERR(chan)) {
+				if (PTR_ERR(chan) != -EPROBE_DEFER)
+					dev_err(&pdev->dev,
+						"no %s DMA channel: %ld\n",
+						name, PTR_ERR(chan));
+
+				ret = PTR_ERR(chan);
+				goto err_release;
+			}
+
+			cl->dma_chans[stream] = chan;
+		}
+
+		fe->id = i;
+		fe->name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-pcm-%d", i);
+		if (!fe->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		fe->ops = &mca_fe_ops;
+		fe->playback.channels_min = 1;
+		fe->playback.channels_max = 32;
+		fe->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->playback.formats = APPLE_MCA_FMTBITS;
+		fe->capture.channels_min = 1;
+		fe->capture.channels_max = 32;
+		fe->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->capture.formats = APPLE_MCA_FMTBITS;
+		fe->symmetric_rate = 1;
+
+		fe->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d TX", i);
+		fe->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d RX", i);
+
+		if (!fe->playback.stream_name || !fe->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+
+		be->id = i + nclusters;
+		be->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-i2s-%d", i);
+		if (!be->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		be->ops = &mca_be_ops;
+		be->playback.channels_min = 1;
+		be->playback.channels_max = 32;
+		be->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		be->playback.formats = APPLE_MCA_FMTBITS;
+		be->capture.channels_min = 1;
+		be->capture.channels_max = 32;
+		be->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		be->capture.formats = APPLE_MCA_FMTBITS;
+
+		be->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d TX", i);
+		be->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d RX", i);
+		if (!be->playback.stream_name || !be->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+	}
+
+	ret = devm_snd_soc_register_component(&pdev->dev, &mca_component,
+					      dai_drivers, nclusters * 2);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to register ASoC component: %d\n",
+			ret);
+		goto err_release;
+	}
+
+	return 0;
+
+err_release:
+	apple_mca_release(mca);
+	return ret;
+}
+
+static int apple_mca_remove(struct platform_device *pdev)
+{
+	struct mca_data *mca = platform_get_drvdata(pdev);
+
+	apple_mca_release(mca);
+	return 0;
+}
+
+static const struct of_device_id apple_mca_of_match[] = {
+	{ .compatible = "apple,mca", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, apple_mca_of_match);
+
+static struct platform_driver apple_mca_driver = {
+	.driver = {
+		.name = "apple-mca",
+		.of_match_table = apple_mca_of_match,
+	},
+	.probe = apple_mca_probe,
+	.remove = apple_mca_remove,
+};
+module_platform_driver(apple_mca_driver);
+
+MODULE_AUTHOR("Martin Povišer <povik+lin@cutebit.org>");
+MODULE_DESCRIPTION("ASoC Apple MCA driver");
+MODULE_LICENSE("GPL");
-- 
2.33.0


^ permalink raw reply related	[relevance 5%]

* [PATCH 2/3] ASoC: apple: mca: Start new platform driver
  @ 2022-08-08 22:41  5%   ` Martin Povišer
  0 siblings, 0 replies; 200+ results
From: Martin Povišer @ 2022-08-08 22:41 UTC (permalink / raw)
  To: Martin Povišer, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Jaroslav Kysela, Takashi Iwai, Philipp Zabel
  Cc: asahi, alsa-devel, devicetree, linux-kernel

Add ASoC platform driver for the MCA peripheral found on Apple M1 and
other chips.

Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
---
 MAINTAINERS              |    8 +
 sound/soc/Kconfig        |    1 +
 sound/soc/Makefile       |    1 +
 sound/soc/apple/Kconfig  |    9 +
 sound/soc/apple/Makefile |    3 +
 sound/soc/apple/mca.c    | 1152 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 1174 insertions(+)
 create mode 100644 sound/soc/apple/Kconfig
 create mode 100644 sound/soc/apple/Makefile
 create mode 100644 sound/soc/apple/mca.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 64379c699903..071d11f88140 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1861,6 +1861,14 @@ F:	include/dt-bindings/pinctrl/apple.h
 F:	include/linux/apple-mailbox.h
 F:	include/linux/soc/apple/*
 
+ARM/APPLE MACHINE SOUND DRIVERS
+M:	Martin Povišer <povik+lin@cutebit.org>
+L:	asahi@lists.linux.dev
+L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/sound/apple,*
+F:	drivers/sound/apple/*
+
 ARM/ARTPEC MACHINE SUPPORT
 M:	Jesper Nilsson <jesper.nilsson@axis.com>
 M:	Lars Persson <lars.persson@axis.com>
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 7d4747b6bab2..848fbae26c3b 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -68,6 +68,7 @@ config SND_SOC_ACPI
 # All the supported SoCs
 source "sound/soc/adi/Kconfig"
 source "sound/soc/amd/Kconfig"
+source "sound/soc/apple/Kconfig"
 source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
 source "sound/soc/bcm/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index d4528962ac34..9b198d4edf37 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SND_SOC_ACPI) += snd-soc-acpi.o
 obj-$(CONFIG_SND_SOC)	+= snd-soc-core.o
 obj-$(CONFIG_SND_SOC)	+= codecs/
 obj-$(CONFIG_SND_SOC)	+= generic/
+obj-$(CONFIG_SND_SOC)	+= apple/
 obj-$(CONFIG_SND_SOC)	+= adi/
 obj-$(CONFIG_SND_SOC)	+= amd/
 obj-$(CONFIG_SND_SOC)	+= atmel/
diff --git a/sound/soc/apple/Kconfig b/sound/soc/apple/Kconfig
new file mode 100644
index 000000000000..0ba955657e98
--- /dev/null
+++ b/sound/soc/apple/Kconfig
@@ -0,0 +1,9 @@
+config SND_SOC_APPLE_MCA
+	tristate "Apple Silicon MCA driver"
+	depends on ARCH_APPLE || COMPILE_TEST
+	select SND_DMAENGINE_PCM
+	select COMMON_CLK
+	default ARCH_APPLE
+	help
+	  This option enables an ASoC platform driver for MCA peripherals found
+	  on Apple Silicon SoCs.
diff --git a/sound/soc/apple/Makefile b/sound/soc/apple/Makefile
new file mode 100644
index 000000000000..7a30bf452817
--- /dev/null
+++ b/sound/soc/apple/Makefile
@@ -0,0 +1,3 @@
+snd-soc-apple-mca-objs	:= mca.o
+
+obj-$(CONFIG_SND_SOC_APPLE_MCA)	+= snd-soc-apple-mca.o
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
new file mode 100644
index 000000000000..ab41fd1a2444
--- /dev/null
+++ b/sound/soc/apple/mca.c
@@ -0,0 +1,1152 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Apple SoCs MCA driver
+ *
+ * Copyright (C) The Asahi Linux Contributors
+ *
+ * The MCA peripheral is made up of a number of identical units called clusters.
+ * Each cluster has its separate clock parent, SYNC signal generator, carries
+ * four SERDES units and has a dedicated I2S port on the SoC's periphery.
+ *
+ * The clusters can operate independently, or can be combined together in a
+ * configurable manner. We mostly treat them as self-contained independent
+ * units and don't configure any cross-cluster connections except for the I2S
+ * ports. The I2S ports can be routed to any of the clusters (irrespective
+ * of their native cluster). We map this onto ASoC's (DPCM) notion of backend
+ * and frontend DAIs. The 'cluster guts' are frontends which are dynamically
+ * routed to backend I2S ports.
+ *
+ * DAI references in devicetree are resolved to backends. The routing between
+ * frontends and backends is determined by the machine driver in the DAPM paths
+ * it supplies.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_clk.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+
+#define USE_RXB_FOR_CAPTURE
+
+/* Relative to cluster base */
+#define REG_STATUS		0x0
+#define STATUS_MCLK_EN		BIT(0)
+#define REG_MCLK_CONF		0x4
+#define MCLK_CONF_DIV		GENMASK(11, 8)
+
+#define REG_SYNCGEN_STATUS	0x100
+#define SYNCGEN_STATUS_EN	BIT(0)
+#define REG_SYNCGEN_MCLK_SEL	0x104
+#define SYNCGEN_MCLK_SEL	GENMASK(3, 0)
+#define REG_SYNCGEN_HI_PERIOD	0x108
+#define REG_SYNCGEN_LO_PERIOD	0x10c
+
+#define REG_PORT_ENABLES	0x600
+#define PORT_ENABLES_CLOCKS	GENMASK(2, 1)
+#define PORT_ENABLES_TX_DATA	BIT(3)
+#define REG_PORT_CLOCK_SEL	0x604
+#define PORT_CLOCK_SEL		GENMASK(11, 8)
+#define REG_PORT_DATA_SEL	0x608
+#define PORT_DATA_SEL_TXA(cl)	(1 << ((cl)*2))
+#define PORT_DATA_SEL_TXB(cl)	(2 << ((cl)*2))
+
+#define REG_INTSTATE		0x700
+#define REG_INTMASK		0x704
+
+/* Bases of serdes units (relative to cluster) */
+#define CLUSTER_RXA_OFF	0x200
+#define CLUSTER_TXA_OFF	0x300
+#define CLUSTER_RXB_OFF	0x400
+#define CLUSTER_TXB_OFF	0x500
+
+#define CLUSTER_TX_OFF	CLUSTER_TXA_OFF
+
+#ifndef USE_RXB_FOR_CAPTURE
+#define CLUSTER_RX_OFF	CLUSTER_RXA_OFF
+#else
+#define CLUSTER_RX_OFF	CLUSTER_RXB_OFF
+#endif
+
+/* Relative to serdes unit base */
+#define REG_SERDES_STATUS	0x00
+#define SERDES_STATUS_EN	BIT(0)
+#define SERDES_STATUS_RST	BIT(1)
+#define REG_TX_SERDES_CONF	0x04
+#define REG_RX_SERDES_CONF	0x08
+#define SERDES_CONF_NCHANS	GENMASK(3, 0)
+#define SERDES_CONF_WIDTH_MASK	GENMASK(8, 4)
+#define SERDES_CONF_WIDTH_16BIT 0x40
+#define SERDES_CONF_WIDTH_20BIT 0x80
+#define SERDES_CONF_WIDTH_24BIT 0xc0
+#define SERDES_CONF_WIDTH_32BIT 0x100
+#define SERDES_CONF_BCLK_POL	0x400
+#define SERDES_CONF_LSB_FIRST	0x800
+#define SERDES_CONF_UNK1	BIT(12)
+#define SERDES_CONF_UNK2	BIT(13)
+#define SERDES_CONF_UNK3	BIT(14)
+#define SERDES_CONF_NO_DATA_FEEDBACK	BIT(15)
+#define SERDES_CONF_SYNC_SEL	GENMASK(18, 16)
+#define SERDES_CONF_SOME_RST	BIT(19)
+#define REG_TX_SERDES_BITSTART	0x08
+#define REG_RX_SERDES_BITSTART	0x0c
+#define REG_TX_SERDES_SLOTMASK	0x0c
+#define REG_RX_SERDES_SLOTMASK	0x10
+#define REG_RX_SERDES_PORT	0x04
+
+/* Relative to switch base */
+#define REG_DMA_ADAPTER_A(cl)	(0x8000 * (cl))
+#define REG_DMA_ADAPTER_B(cl)	(0x8000 * (cl) + 0x4000)
+#define DMA_ADAPTER_TX_LSB_PAD	GENMASK(4, 0)
+#define DMA_ADAPTER_TX_NCHANS	GENMASK(6, 5)
+#define DMA_ADAPTER_RX_MSB_PAD	GENMASK(12, 8)
+#define DMA_ADAPTER_RX_NCHANS	GENMASK(14, 13)
+#define DMA_ADAPTER_NCHANS	GENMASK(22, 20)
+
+#define SWITCH_STRIDE	0x8000
+#define CLUSTER_STRIDE	0x4000
+
+#define MAX_NCLUSTERS	6
+
+#define APPLE_MCA_FMTBITS (SNDRV_PCM_FMTBIT_S16_LE | \
+			   SNDRV_PCM_FMTBIT_S24_LE | \
+			   SNDRV_PCM_FMTBIT_S32_LE)
+
+struct mca_cluster {
+	int no;
+	__iomem void *base;
+	struct mca_data *host;
+	struct device *pd_dev;
+	struct clk *clk_parent;
+	struct dma_chan *dma_chans[SNDRV_PCM_STREAM_LAST + 1];
+
+	bool port_started[SNDRV_PCM_STREAM_LAST + 1];
+	int port_driver; /* The cluster driving this cluster's port */
+
+	bool clocks_in_use[SNDRV_PCM_STREAM_LAST + 1];
+	struct device_link *pd_link;
+
+	unsigned int bclk_ratio;
+
+	/* Masks etc. picked up via the set_tdm_slot method */
+	int tdm_slots;
+	int tdm_slot_width;
+	unsigned int tdm_tx_mask;
+	unsigned int tdm_rx_mask;
+};
+
+struct mca_data {
+	struct device *dev;
+
+	__iomem void *switch_base;
+
+	struct device *pd_dev;
+	struct reset_control *rstc;
+	struct device_link *pd_link;
+
+	int nclusters;
+	struct mca_cluster clusters[];
+};
+
+static void mca_modify(struct mca_cluster *cl, int regoffset, u32 mask, u32 val)
+{
+	__iomem void *ptr = cl->base + regoffset;
+	u32 newval;
+
+	newval = (val & mask) | (readl_relaxed(ptr) & ~mask);
+	writel_relaxed(newval, ptr);
+}
+
+/*
+ * Get the cluster of FE or BE DAI
+ */
+static struct mca_cluster *mca_dai_to_cluster(struct snd_soc_dai *dai)
+{
+	struct mca_data *mca = snd_soc_dai_get_drvdata(dai);
+	/*
+	 * FE DAIs are         0 ... nclusters - 1
+	 * BE DAIs are nclusters ... 2*nclusters - 1
+	 */
+	int cluster_no = dai->id % mca->nclusters;
+
+	return &mca->clusters[cluster_no];
+}
+
+/* called before PCM trigger */
+static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
+				 struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+	int serdes_conf =
+		serdes_unit + (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_RST);
+		mca_modify(cl, serdes_conf, SERDES_CONF_SOME_RST,
+			   SERDES_CONF_SOME_RST);
+		readl_relaxed(cl->base + serdes_conf);
+		mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
+		WARN_ON(readl_relaxed(cl->base + REG_SERDES_STATUS) &
+			SERDES_STATUS_RST);
+		break;
+	default:
+		break;
+	}
+}
+
+static int mca_fe_trigger(struct snd_pcm_substream *substream, int cmd,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_EN);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mca_fe_enable_clocks(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	int ret;
+
+	ret = clk_prepare_enable(cl->clk_parent);
+	if (ret) {
+		dev_err(mca->dev,
+			"cluster %d: unable to enable clock parent: %d\n",
+			cl->no, ret);
+		return ret;
+	}
+
+	/*
+	 * We can't power up the device earlier than this because
+	 * the power state driver would error out on seeing the device
+	 * as clock-gated.
+	 */
+	cl->pd_link = device_link_add(mca->dev, cl->pd_dev,
+				      DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					      DL_FLAG_RPM_ACTIVE);
+	if (!cl->pd_link) {
+		dev_err(mca->dev,
+			"cluster %d: unable to prop-up power domain\n", cl->no);
+		clk_disable_unprepare(cl->clk_parent);
+		return -EINVAL;
+	}
+
+	writel_relaxed(cl->no + 1, cl->base + REG_SYNCGEN_MCLK_SEL);
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN,
+		   SYNCGEN_STATUS_EN);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, STATUS_MCLK_EN);
+
+	return 0;
+}
+
+static void mca_fe_disable_clocks(struct mca_cluster *cl)
+{
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN, 0);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, 0);
+
+	device_link_del(cl->pd_link);
+	clk_disable_unprepare(cl->clk_parent);
+}
+
+static bool mca_fe_clocks_in_use(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *be_cl;
+	int stream, i;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		be_cl = &mca->clusters[i];
+
+		if (be_cl->port_driver != cl->no)
+			continue;
+
+		for_each_pcm_streams(stream)
+			if (be_cl->clocks_in_use[stream])
+				return true;
+	}
+	return false;
+}
+
+static int mca_be_prepare(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+	int ret;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+
+	/*
+	 * Typically the CODECs we are paired with will require clocks
+	 * to be present at time of unmute with the 'mute_stream' op
+	 * or at time of DAPM widget power-up. We need to enable clocks
+	 * here at the latest (frontend prepare would be too late).
+	 */
+	if (!mca_fe_clocks_in_use(fe_cl)) {
+		ret = mca_fe_enable_clocks(fe_cl);
+		if (ret < 0)
+			return ret;
+	}
+
+	cl->clocks_in_use[substream->stream] = true;
+
+	return 0;
+}
+
+static int mca_be_hw_free(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+	if (!mca_fe_clocks_in_use(fe_cl))
+		return 0; /* Nothing to do */
+
+	cl->clocks_in_use[substream->stream] = false;
+
+	if (!mca_fe_clocks_in_use(fe_cl))
+		mca_fe_disable_clocks(fe_cl);
+
+	return 0;
+}
+
+static unsigned int mca_crop_mask(unsigned int mask, int nchans)
+{
+	while (hweight32(mask) > nchans)
+		mask &= ~(1 << __fls(mask));
+
+	return mask;
+}
+
+static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
+				unsigned int mask, int slots, int nchans,
+				int slot_width, bool is_tx, int port)
+{
+	__iomem void *serdes_base = cl->base + serdes_unit;
+	u32 serdes_conf, serdes_conf_mask;
+
+	serdes_conf_mask = SERDES_CONF_WIDTH_MASK | SERDES_CONF_NCHANS;
+	serdes_conf = FIELD_PREP(SERDES_CONF_NCHANS, max(slots, 1) - 1);
+	switch (slot_width) {
+	case 16:
+		serdes_conf |= SERDES_CONF_WIDTH_16BIT;
+		break;
+	case 20:
+		serdes_conf |= SERDES_CONF_WIDTH_20BIT;
+		break;
+	case 24:
+		serdes_conf |= SERDES_CONF_WIDTH_24BIT;
+		break;
+	case 32:
+		serdes_conf |= SERDES_CONF_WIDTH_32BIT;
+		break;
+	default:
+		goto err;
+	}
+
+	serdes_conf_mask |= SERDES_CONF_SYNC_SEL;
+	serdes_conf |= FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1);
+
+	if (is_tx) {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_UNK3;
+	} else {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3 |
+				    SERDES_CONF_NO_DATA_FEEDBACK;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_NO_DATA_FEEDBACK;
+	}
+
+	mca_modify(cl,
+		   serdes_unit +
+			   (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF),
+		   serdes_conf_mask, serdes_conf);
+
+	if (is_tx) {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x8);
+		writel_relaxed(~((u32)mask),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0xc);
+	} else {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_RX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_RX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(1 << port,
+			       serdes_base + REG_RX_SERDES_PORT);
+	}
+
+	return 0;
+
+err:
+	dev_err(cl->host->dev,
+		"unsupported SERDES configuration requested (mask=0x%x slots=%d slot_width=%d)\n",
+		mask, slots, slot_width);
+	return -EINVAL;
+}
+
+static int mca_fe_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+			       unsigned int rx_mask, int slots, int slot_width)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->tdm_slots = slots;
+	cl->tdm_slot_width = slot_width;
+	cl->tdm_tx_mask = tx_mask;
+	cl->tdm_rx_mask = rx_mask;
+
+	return 0;
+}
+
+static int mca_fe_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	bool fpol_inv = false;
+	u32 serdes_conf = 0;
+	u32 bitstart;
+
+	if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) !=
+	    SND_SOC_DAIFMT_CBC_CFC)
+		goto err;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		fpol_inv = 0;
+		bitstart = 1;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		fpol_inv = 1;
+		bitstart = 0;
+		break;
+	default:
+		goto err;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_IF:
+	case SND_SOC_DAIFMT_IB_IF:
+		fpol_inv ^= 1;
+		break;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+	case SND_SOC_DAIFMT_NB_IF:
+		serdes_conf |= SERDES_CONF_BCLK_POL;
+		break;
+	}
+
+	if (!fpol_inv)
+		goto err;
+
+	mca_modify(cl, CLUSTER_TX_OFF + REG_TX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	mca_modify(cl, CLUSTER_RX_OFF + REG_RX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_TX_OFF + REG_TX_SERDES_BITSTART);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_RX_OFF + REG_RX_SERDES_BITSTART);
+
+	return 0;
+
+err:
+	dev_err(mca->dev, "unsupported DAI format (0x%x) requested\n", fmt);
+	return -EINVAL;
+}
+
+static int mca_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->bclk_ratio = ratio;
+
+	return 0;
+}
+
+static int mca_fe_get_port(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *be;
+	struct snd_soc_dpcm *dpcm;
+
+	be = NULL;
+	for_each_dpcm_be(fe, substream->stream, dpcm) {
+		be = dpcm->be;
+		break;
+	}
+
+	if (!be)
+		return -EINVAL;
+
+	return mca_dai_to_cluster(asoc_rtd_to_cpu(be, 0))->no;
+}
+
+static int mca_fe_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct device *dev = mca->dev;
+	unsigned int samp_rate = params_rate(params);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	bool refine_tdm = false;
+	unsigned long bclk_ratio;
+	unsigned int tdm_slots, tdm_slot_width, tdm_mask;
+	u32 regval, pad;
+	int ret, port, nchans_ceiled;
+
+	if (!cl->tdm_slot_width) {
+		/*
+		 * We were not given TDM settings from above, set initial
+		 * guesses which will later be refined.
+		 */
+		tdm_slot_width = params_width(params);
+		tdm_slots = params_channels(params);
+		refine_tdm = true;
+	} else {
+		tdm_slot_width = cl->tdm_slot_width;
+		tdm_slots = cl->tdm_slots;
+		tdm_mask = is_tx ? cl->tdm_tx_mask : cl->tdm_rx_mask;
+	}
+
+	if (cl->bclk_ratio)
+		bclk_ratio = cl->bclk_ratio;
+	else
+		bclk_ratio = tdm_slot_width * tdm_slots;
+
+	if (refine_tdm) {
+		int nchannels = params_channels(params);
+
+		if (nchannels > 2) {
+			dev_err(dev, "missing TDM for stream with two or more channels\n");
+			return -EINVAL;
+		}
+
+		if ((bclk_ratio % nchannels) != 0) {
+			dev_err(dev, "BCLK ratio (%ld) not divisible by no. of channels (%d)\n",
+				bclk_ratio, nchannels);
+			return -EINVAL;
+		}
+
+		tdm_slot_width = bclk_ratio / nchannels;
+
+		if (tdm_slot_width > 32 && nchannels == 1)
+			tdm_slot_width = 32;
+
+		if (tdm_slot_width < params_width(params)) {
+			dev_err(dev, "TDM slots too narrow (tdm=%d params=%d)\n",
+				tdm_slot_width, params_width(params));
+			return -EINVAL;
+		}
+
+		tdm_mask = (1 << tdm_slots) - 1;
+	}
+
+	port = mca_fe_get_port(substream);
+	if (port < 0)
+		return port;
+
+	ret = mca_configure_serdes(cl, is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF,
+				   tdm_mask, tdm_slots, params_channels(params),
+				   tdm_slot_width, is_tx, port);
+	if (ret)
+		return ret;
+
+	pad = 32 - params_width(params);
+
+	/*
+	 * TODO: Here the register semantics aren't clear.
+	 */
+	nchans_ceiled = min_t(int, params_channels(params), 4);
+	regval = FIELD_PREP(DMA_ADAPTER_NCHANS, nchans_ceiled) |
+		 FIELD_PREP(DMA_ADAPTER_TX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_RX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_TX_LSB_PAD, pad) |
+		 FIELD_PREP(DMA_ADAPTER_RX_MSB_PAD, pad);
+
+#ifndef USE_RXB_FOR_CAPTURE
+	writel_relaxed(regval, mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+#else
+	if (is_tx)
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+	else
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_B(cl->no));
+#endif
+
+	if (!mca_fe_clocks_in_use(cl)) {
+		/*
+		 * Set up FSYNC duty cycle as even as possible.
+		 */
+		writel_relaxed((bclk_ratio / 2) - 1,
+			       cl->base + REG_SYNCGEN_HI_PERIOD);
+		writel_relaxed(((bclk_ratio + 1) / 2) - 1,
+			       cl->base + REG_SYNCGEN_LO_PERIOD);
+		writel_relaxed(FIELD_PREP(MCLK_CONF_DIV, 0x1),
+			       cl->base + REG_MCLK_CONF);
+
+		ret = clk_set_rate(cl->clk_parent, bclk_ratio * samp_rate);
+		if (ret) {
+			dev_err(mca->dev, "cluster %d: unable to set clock parent: %d\n",
+				cl->no, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops mca_fe_ops = {
+	.set_fmt = mca_fe_set_fmt,
+	.set_bclk_ratio = mca_set_bclk_ratio,
+	.set_tdm_slot = mca_fe_set_tdm_slot,
+	.hw_params = mca_fe_hw_params,
+	.trigger = mca_fe_trigger,
+};
+
+static bool mca_be_started(struct mca_cluster *cl)
+{
+	int stream;
+
+	for_each_pcm_streams(stream)
+		if (cl->port_started[stream])
+			return true;
+	return false;
+}
+
+static int mca_be_startup(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *be = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *fe;
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_cluster *fe_cl;
+	struct mca_data *mca = cl->host;
+	struct snd_soc_dpcm *dpcm;
+
+	fe = NULL;
+
+	for_each_dpcm_fe(be, substream->stream, dpcm) {
+		if (fe && dpcm->fe != fe) {
+			dev_err(mca->dev, "many FE per one BE unsupported\n");
+			return -EINVAL;
+		}
+
+		fe = dpcm->fe;
+	}
+
+	if (!fe)
+		return -EINVAL;
+
+	fe_cl = mca_dai_to_cluster(asoc_rtd_to_cpu(fe, 0));
+
+	if (mca_be_started(cl)) {
+		/*
+		 * Port is already started in the other direction.
+		 * Make sure there isn't a conflict with another cluster
+		 * driving the port.
+		 */
+		if (cl->port_driver != fe_cl->no)
+			return -EINVAL;
+
+		cl->port_started[substream->stream] = true;
+		return 0;
+	}
+
+	writel_relaxed(PORT_ENABLES_CLOCKS | PORT_ENABLES_TX_DATA,
+		       cl->base + REG_PORT_ENABLES);
+	writel_relaxed(FIELD_PREP(PORT_CLOCK_SEL, fe_cl->no + 1),
+		       cl->base + REG_PORT_CLOCK_SEL);
+	writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no),
+		       cl->base + REG_PORT_DATA_SEL);
+	cl->port_driver = fe_cl->no;
+	cl->port_started[substream->stream] = true;
+
+	return 0;
+}
+
+static void mca_be_shutdown(struct snd_pcm_substream *substream,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->port_started[substream->stream] = false;
+
+	if (!mca_be_started(cl)) {
+		/*
+		 * Were we the last direction to shutdown?
+		 * Turn off the lights.
+		 */
+		writel_relaxed(0, cl->base + REG_PORT_ENABLES);
+		writel_relaxed(0, cl->base + REG_PORT_DATA_SEL);
+		cl->port_driver = -1;
+	}
+}
+
+static const struct snd_soc_dai_ops mca_be_ops = {
+	.prepare = mca_be_prepare,
+	.hw_free = mca_be_hw_free,
+	.startup = mca_be_startup,
+	.shutdown = mca_be_shutdown,
+};
+
+static int mca_set_runtime_hwparams(struct snd_soc_component *component,
+				    struct snd_pcm_substream *substream,
+				    struct dma_chan *chan)
+{
+	struct device *dma_dev = chan->device->dev;
+	struct snd_dmaengine_dai_dma_data dma_data = {};
+	int ret;
+
+	struct snd_pcm_hardware hw;
+
+	memset(&hw, 0, sizeof(hw));
+
+	hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+		  SNDRV_PCM_INFO_INTERLEAVED;
+	hw.periods_min = 2;
+	hw.periods_max = UINT_MAX;
+	hw.period_bytes_min = 256;
+	hw.period_bytes_max = dma_get_max_seg_size(dma_dev);
+	hw.buffer_bytes_max = SIZE_MAX;
+	hw.fifo_size = 16;
+
+	ret = snd_dmaengine_pcm_refine_runtime_hwparams(substream, &dma_data,
+							&hw, chan);
+
+	if (ret)
+		return ret;
+
+	return snd_soc_set_runtime_hwparams(substream, &hw);
+}
+
+static int mca_pcm_open(struct snd_soc_component *component,
+			struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	struct dma_chan *chan = cl->dma_chans[substream->stream];
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	ret = mca_set_runtime_hwparams(component, substream, chan);
+	if (ret)
+		return ret;
+
+	return snd_dmaengine_pcm_open(substream, chan);
+}
+
+static int mca_hw_params(struct snd_soc_component *component,
+			 struct snd_pcm_substream *substream,
+			 struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
+	struct dma_slave_config slave_config;
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	memset(&slave_config, 0, sizeof(slave_config));
+	ret = snd_hwparams_to_dma_slave_config(substream, params,
+					       &slave_config);
+	if (ret < 0)
+		return ret;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		slave_config.dst_port_window_size =
+			min_t(u32, params_channels(params), 4);
+	else
+		slave_config.src_port_window_size =
+			min_t(u32, params_channels(params), 4);
+
+	return dmaengine_slave_config(chan, &slave_config);
+}
+
+static int mca_close(struct snd_soc_component *component,
+		     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	return snd_dmaengine_pcm_close(substream);
+}
+
+static int mca_trigger(struct snd_soc_component *component,
+		       struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	/*
+	 * Before we do the PCM trigger proper, insert an opportunity
+	 * to reset the frontend's SERDES.
+	 */
+	mca_fe_early_trigger(substream, cmd, asoc_rtd_to_cpu(rtd, 0));
+
+	return snd_dmaengine_pcm_trigger(substream, cmd);
+}
+
+static snd_pcm_uframes_t mca_pointer(struct snd_soc_component *component,
+				     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return -ENOTSUPP;
+
+	return snd_dmaengine_pcm_pointer(substream);
+}
+
+static int mca_pcm_new(struct snd_soc_component *component,
+		       struct snd_soc_pcm_runtime *rtd)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	unsigned int i;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	for_each_pcm_streams(i) {
+		struct snd_pcm_substream *substream =
+			rtd->pcm->streams[i].substream;
+		struct dma_chan *chan = cl->dma_chans[i];
+
+		if (!substream)
+			continue;
+
+		if (!chan) {
+			dev_err(component->dev, "missing DMA channel for stream %d on SERDES %d\n",
+				i, cl->no);
+			return -EINVAL;
+		}
+
+		snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV_IRAM,
+					   chan->device->dev, 512 * 1024 * 6,
+					   SIZE_MAX);
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_component_driver mca_component = {
+	.name = "apple-mca",
+	.open = mca_pcm_open,
+	.close = mca_close,
+	.hw_params = mca_hw_params,
+	.trigger = mca_trigger,
+	.pointer = mca_pointer,
+	.pcm_construct = mca_pcm_new,
+};
+
+static void apple_mca_release(struct mca_data *mca)
+{
+	int i, stream;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		struct mca_cluster *cl = &mca->clusters[i];
+
+		for_each_pcm_streams(stream) {
+			if (IS_ERR_OR_NULL(cl->dma_chans[stream]))
+				continue;
+
+			dma_release_channel(cl->dma_chans[stream]);
+		}
+
+		if (!IS_ERR_OR_NULL(cl->clk_parent))
+			clk_put(cl->clk_parent);
+
+		if (!IS_ERR_OR_NULL(cl->pd_dev))
+			dev_pm_domain_detach(cl->pd_dev, true);
+	}
+
+	if (mca->pd_link)
+		device_link_del(mca->pd_link);
+
+	if (!IS_ERR_OR_NULL(mca->pd_dev))
+		dev_pm_domain_detach(mca->pd_dev, true);
+
+	reset_control_assert(mca->rstc);
+}
+
+static int apple_mca_probe(struct platform_device *pdev)
+{
+	struct mca_data *mca;
+	struct mca_cluster *clusters;
+	struct snd_soc_dai_driver *dai_drivers;
+	struct resource *res;
+	void __iomem *base;
+	int nclusters;
+	int ret, i;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	if (resource_size(res) < CLUSTER_STRIDE)
+		return -EINVAL;
+	nclusters = (resource_size(res) - CLUSTER_STRIDE) / CLUSTER_STRIDE + 1;
+
+	mca = devm_kzalloc(&pdev->dev, struct_size(mca, clusters, nclusters),
+			   GFP_KERNEL);
+	if (!mca)
+		return -ENOMEM;
+	mca->dev = &pdev->dev;
+	mca->nclusters = nclusters;
+	platform_set_drvdata(pdev, mca);
+	clusters = mca->clusters;
+
+	mca->switch_base =
+		devm_platform_ioremap_resource_byname(pdev, "switch");
+	if (IS_ERR(mca->switch_base))
+		return PTR_ERR(mca->switch_base);
+
+	mca->rstc = devm_reset_control_get_shared(&pdev->dev, NULL);
+	if (IS_ERR(mca->rstc)) {
+		dev_dbg(&pdev->dev, "couldn't obtain reset control: %pe\n", mca->rstc);
+		mca->rstc = NULL;
+	}
+
+	dai_drivers = devm_kzalloc(
+		&pdev->dev, sizeof(*dai_drivers) * 2 * nclusters, GFP_KERNEL);
+	if (!dai_drivers)
+		return -ENOMEM;
+
+	mca->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, 0);
+	if (IS_ERR(mca->pd_dev))
+		return -EINVAL;
+
+	mca->pd_link = device_link_add(&pdev->dev, mca->pd_dev,
+				       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					       DL_FLAG_RPM_ACTIVE);
+	if (!mca->pd_link) {
+		ret = -EINVAL;
+		/* Prevent an unbalanced reset assert */
+		mca->rstc = NULL;
+		goto err_release;
+	}
+
+	reset_control_deassert(mca->rstc);
+
+	for (i = 0; i < nclusters; i++) {
+		struct mca_cluster *cl = &clusters[i];
+		struct snd_soc_dai_driver *fe =
+			&dai_drivers[mca->nclusters + i];
+		struct snd_soc_dai_driver *be = &dai_drivers[i];
+		int stream;
+
+		cl->host = mca;
+		cl->no = i;
+		cl->base = base + CLUSTER_STRIDE * i;
+		cl->port_driver = -1;
+		cl->clk_parent = of_clk_get(pdev->dev.of_node, i);
+		if (IS_ERR(cl->clk_parent)) {
+			dev_err(&pdev->dev, "unable to obtain clock %d: %ld\n",
+				i, PTR_ERR(cl->clk_parent));
+			ret = PTR_ERR(cl->clk_parent);
+			goto err_release;
+		}
+		cl->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, i + 1);
+		if (IS_ERR(cl->pd_dev)) {
+			dev_err(&pdev->dev,
+				"unable to obtain cluster %d PD: %ld\n", i,
+				PTR_ERR(cl->pd_dev));
+			ret = PTR_ERR(cl->pd_dev);
+			goto err_release;
+		}
+
+		for_each_pcm_streams(stream) {
+			struct dma_chan *chan;
+			bool is_tx = (stream == SNDRV_PCM_STREAM_PLAYBACK);
+#ifndef USE_RXB_FOR_CAPTURE
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%da",
+						    i);
+#else
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%db",
+						    i);
+#endif
+
+			chan = of_dma_request_slave_channel(pdev->dev.of_node,
+							    name);
+			if (IS_ERR(chan)) {
+				if (PTR_ERR(chan) != -EPROBE_DEFER)
+					dev_err(&pdev->dev,
+						"no %s DMA channel: %ld\n",
+						name, PTR_ERR(chan));
+
+				ret = PTR_ERR(chan);
+				goto err_release;
+			}
+
+			cl->dma_chans[stream] = chan;
+		}
+
+		fe->id = i;
+		fe->name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-pcm-%d", i);
+		if (!fe->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		fe->ops = &mca_fe_ops;
+		fe->playback.channels_min = 1;
+		fe->playback.channels_max = 32;
+		fe->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->playback.formats = APPLE_MCA_FMTBITS;
+		fe->capture.channels_min = 1;
+		fe->capture.channels_max = 32;
+		fe->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->capture.formats = APPLE_MCA_FMTBITS;
+		fe->symmetric_rate = 1;
+
+		fe->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d TX", i);
+		fe->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d RX", i);
+
+		if (!fe->playback.stream_name || !fe->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+
+		be->id = i + nclusters;
+		be->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-i2s-%d", i);
+		if (!be->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		be->ops = &mca_be_ops;
+		be->playback.channels_min = 1;
+		be->playback.channels_max = 32;
+		be->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		be->playback.formats = APPLE_MCA_FMTBITS;
+		be->capture.channels_min = 1;
+		be->capture.channels_max = 32;
+		be->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		be->capture.formats = APPLE_MCA_FMTBITS;
+
+		be->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d TX", i);
+		be->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d RX", i);
+		if (!be->playback.stream_name || !be->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+	}
+
+	ret = devm_snd_soc_register_component(&pdev->dev, &mca_component,
+					      dai_drivers, nclusters * 2);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to register ASoC component: %d\n",
+			ret);
+		goto err_release;
+	}
+
+	return 0;
+
+err_release:
+	apple_mca_release(mca);
+	return ret;
+}
+
+static int apple_mca_remove(struct platform_device *pdev)
+{
+	struct mca_data *mca = platform_get_drvdata(pdev);
+
+	apple_mca_release(mca);
+	return 0;
+}
+
+static const struct of_device_id apple_mca_of_match[] = {
+	{ .compatible = "apple,mca", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, apple_mca_of_match);
+
+static struct platform_driver apple_mca_driver = {
+	.driver = {
+		.name = "apple-mca",
+		.owner = THIS_MODULE,
+		.of_match_table = apple_mca_of_match,
+	},
+	.probe = apple_mca_probe,
+	.remove = apple_mca_remove,
+};
+module_platform_driver(apple_mca_driver);
+
+MODULE_AUTHOR("Martin Povišer <povik+lin@cutebit.org>");
+MODULE_DESCRIPTION("ASoC Apple MCA driver");
+MODULE_LICENSE("GPL");
-- 
2.33.0


^ permalink raw reply related	[relevance 5%]

* [PATCH 2/3] ASoC: apple: mca: Start new platform driver
@ 2022-08-08 22:41  5%   ` Martin Povišer
  0 siblings, 0 replies; 200+ results
From: Martin Povišer @ 2022-08-08 22:41 UTC (permalink / raw)
  To: Martin Povišer, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Jaroslav Kysela, Takashi Iwai, Philipp Zabel
  Cc: devicetree, alsa-devel, asahi, linux-kernel

Add ASoC platform driver for the MCA peripheral found on Apple M1 and
other chips.

Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
---
 MAINTAINERS              |    8 +
 sound/soc/Kconfig        |    1 +
 sound/soc/Makefile       |    1 +
 sound/soc/apple/Kconfig  |    9 +
 sound/soc/apple/Makefile |    3 +
 sound/soc/apple/mca.c    | 1152 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 1174 insertions(+)
 create mode 100644 sound/soc/apple/Kconfig
 create mode 100644 sound/soc/apple/Makefile
 create mode 100644 sound/soc/apple/mca.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 64379c699903..071d11f88140 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1861,6 +1861,14 @@ F:	include/dt-bindings/pinctrl/apple.h
 F:	include/linux/apple-mailbox.h
 F:	include/linux/soc/apple/*
 
+ARM/APPLE MACHINE SOUND DRIVERS
+M:	Martin Povišer <povik+lin@cutebit.org>
+L:	asahi@lists.linux.dev
+L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/sound/apple,*
+F:	drivers/sound/apple/*
+
 ARM/ARTPEC MACHINE SUPPORT
 M:	Jesper Nilsson <jesper.nilsson@axis.com>
 M:	Lars Persson <lars.persson@axis.com>
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 7d4747b6bab2..848fbae26c3b 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -68,6 +68,7 @@ config SND_SOC_ACPI
 # All the supported SoCs
 source "sound/soc/adi/Kconfig"
 source "sound/soc/amd/Kconfig"
+source "sound/soc/apple/Kconfig"
 source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
 source "sound/soc/bcm/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index d4528962ac34..9b198d4edf37 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SND_SOC_ACPI) += snd-soc-acpi.o
 obj-$(CONFIG_SND_SOC)	+= snd-soc-core.o
 obj-$(CONFIG_SND_SOC)	+= codecs/
 obj-$(CONFIG_SND_SOC)	+= generic/
+obj-$(CONFIG_SND_SOC)	+= apple/
 obj-$(CONFIG_SND_SOC)	+= adi/
 obj-$(CONFIG_SND_SOC)	+= amd/
 obj-$(CONFIG_SND_SOC)	+= atmel/
diff --git a/sound/soc/apple/Kconfig b/sound/soc/apple/Kconfig
new file mode 100644
index 000000000000..0ba955657e98
--- /dev/null
+++ b/sound/soc/apple/Kconfig
@@ -0,0 +1,9 @@
+config SND_SOC_APPLE_MCA
+	tristate "Apple Silicon MCA driver"
+	depends on ARCH_APPLE || COMPILE_TEST
+	select SND_DMAENGINE_PCM
+	select COMMON_CLK
+	default ARCH_APPLE
+	help
+	  This option enables an ASoC platform driver for MCA peripherals found
+	  on Apple Silicon SoCs.
diff --git a/sound/soc/apple/Makefile b/sound/soc/apple/Makefile
new file mode 100644
index 000000000000..7a30bf452817
--- /dev/null
+++ b/sound/soc/apple/Makefile
@@ -0,0 +1,3 @@
+snd-soc-apple-mca-objs	:= mca.o
+
+obj-$(CONFIG_SND_SOC_APPLE_MCA)	+= snd-soc-apple-mca.o
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
new file mode 100644
index 000000000000..ab41fd1a2444
--- /dev/null
+++ b/sound/soc/apple/mca.c
@@ -0,0 +1,1152 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Apple SoCs MCA driver
+ *
+ * Copyright (C) The Asahi Linux Contributors
+ *
+ * The MCA peripheral is made up of a number of identical units called clusters.
+ * Each cluster has its separate clock parent, SYNC signal generator, carries
+ * four SERDES units and has a dedicated I2S port on the SoC's periphery.
+ *
+ * The clusters can operate independently, or can be combined together in a
+ * configurable manner. We mostly treat them as self-contained independent
+ * units and don't configure any cross-cluster connections except for the I2S
+ * ports. The I2S ports can be routed to any of the clusters (irrespective
+ * of their native cluster). We map this onto ASoC's (DPCM) notion of backend
+ * and frontend DAIs. The 'cluster guts' are frontends which are dynamically
+ * routed to backend I2S ports.
+ *
+ * DAI references in devicetree are resolved to backends. The routing between
+ * frontends and backends is determined by the machine driver in the DAPM paths
+ * it supplies.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_clk.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+
+#define USE_RXB_FOR_CAPTURE
+
+/* Relative to cluster base */
+#define REG_STATUS		0x0
+#define STATUS_MCLK_EN		BIT(0)
+#define REG_MCLK_CONF		0x4
+#define MCLK_CONF_DIV		GENMASK(11, 8)
+
+#define REG_SYNCGEN_STATUS	0x100
+#define SYNCGEN_STATUS_EN	BIT(0)
+#define REG_SYNCGEN_MCLK_SEL	0x104
+#define SYNCGEN_MCLK_SEL	GENMASK(3, 0)
+#define REG_SYNCGEN_HI_PERIOD	0x108
+#define REG_SYNCGEN_LO_PERIOD	0x10c
+
+#define REG_PORT_ENABLES	0x600
+#define PORT_ENABLES_CLOCKS	GENMASK(2, 1)
+#define PORT_ENABLES_TX_DATA	BIT(3)
+#define REG_PORT_CLOCK_SEL	0x604
+#define PORT_CLOCK_SEL		GENMASK(11, 8)
+#define REG_PORT_DATA_SEL	0x608
+#define PORT_DATA_SEL_TXA(cl)	(1 << ((cl)*2))
+#define PORT_DATA_SEL_TXB(cl)	(2 << ((cl)*2))
+
+#define REG_INTSTATE		0x700
+#define REG_INTMASK		0x704
+
+/* Bases of serdes units (relative to cluster) */
+#define CLUSTER_RXA_OFF	0x200
+#define CLUSTER_TXA_OFF	0x300
+#define CLUSTER_RXB_OFF	0x400
+#define CLUSTER_TXB_OFF	0x500
+
+#define CLUSTER_TX_OFF	CLUSTER_TXA_OFF
+
+#ifndef USE_RXB_FOR_CAPTURE
+#define CLUSTER_RX_OFF	CLUSTER_RXA_OFF
+#else
+#define CLUSTER_RX_OFF	CLUSTER_RXB_OFF
+#endif
+
+/* Relative to serdes unit base */
+#define REG_SERDES_STATUS	0x00
+#define SERDES_STATUS_EN	BIT(0)
+#define SERDES_STATUS_RST	BIT(1)
+#define REG_TX_SERDES_CONF	0x04
+#define REG_RX_SERDES_CONF	0x08
+#define SERDES_CONF_NCHANS	GENMASK(3, 0)
+#define SERDES_CONF_WIDTH_MASK	GENMASK(8, 4)
+#define SERDES_CONF_WIDTH_16BIT 0x40
+#define SERDES_CONF_WIDTH_20BIT 0x80
+#define SERDES_CONF_WIDTH_24BIT 0xc0
+#define SERDES_CONF_WIDTH_32BIT 0x100
+#define SERDES_CONF_BCLK_POL	0x400
+#define SERDES_CONF_LSB_FIRST	0x800
+#define SERDES_CONF_UNK1	BIT(12)
+#define SERDES_CONF_UNK2	BIT(13)
+#define SERDES_CONF_UNK3	BIT(14)
+#define SERDES_CONF_NO_DATA_FEEDBACK	BIT(15)
+#define SERDES_CONF_SYNC_SEL	GENMASK(18, 16)
+#define SERDES_CONF_SOME_RST	BIT(19)
+#define REG_TX_SERDES_BITSTART	0x08
+#define REG_RX_SERDES_BITSTART	0x0c
+#define REG_TX_SERDES_SLOTMASK	0x0c
+#define REG_RX_SERDES_SLOTMASK	0x10
+#define REG_RX_SERDES_PORT	0x04
+
+/* Relative to switch base */
+#define REG_DMA_ADAPTER_A(cl)	(0x8000 * (cl))
+#define REG_DMA_ADAPTER_B(cl)	(0x8000 * (cl) + 0x4000)
+#define DMA_ADAPTER_TX_LSB_PAD	GENMASK(4, 0)
+#define DMA_ADAPTER_TX_NCHANS	GENMASK(6, 5)
+#define DMA_ADAPTER_RX_MSB_PAD	GENMASK(12, 8)
+#define DMA_ADAPTER_RX_NCHANS	GENMASK(14, 13)
+#define DMA_ADAPTER_NCHANS	GENMASK(22, 20)
+
+#define SWITCH_STRIDE	0x8000
+#define CLUSTER_STRIDE	0x4000
+
+#define MAX_NCLUSTERS	6
+
+#define APPLE_MCA_FMTBITS (SNDRV_PCM_FMTBIT_S16_LE | \
+			   SNDRV_PCM_FMTBIT_S24_LE | \
+			   SNDRV_PCM_FMTBIT_S32_LE)
+
+struct mca_cluster {
+	int no;
+	__iomem void *base;
+	struct mca_data *host;
+	struct device *pd_dev;
+	struct clk *clk_parent;
+	struct dma_chan *dma_chans[SNDRV_PCM_STREAM_LAST + 1];
+
+	bool port_started[SNDRV_PCM_STREAM_LAST + 1];
+	int port_driver; /* The cluster driving this cluster's port */
+
+	bool clocks_in_use[SNDRV_PCM_STREAM_LAST + 1];
+	struct device_link *pd_link;
+
+	unsigned int bclk_ratio;
+
+	/* Masks etc. picked up via the set_tdm_slot method */
+	int tdm_slots;
+	int tdm_slot_width;
+	unsigned int tdm_tx_mask;
+	unsigned int tdm_rx_mask;
+};
+
+struct mca_data {
+	struct device *dev;
+
+	__iomem void *switch_base;
+
+	struct device *pd_dev;
+	struct reset_control *rstc;
+	struct device_link *pd_link;
+
+	int nclusters;
+	struct mca_cluster clusters[];
+};
+
+static void mca_modify(struct mca_cluster *cl, int regoffset, u32 mask, u32 val)
+{
+	__iomem void *ptr = cl->base + regoffset;
+	u32 newval;
+
+	newval = (val & mask) | (readl_relaxed(ptr) & ~mask);
+	writel_relaxed(newval, ptr);
+}
+
+/*
+ * Get the cluster of FE or BE DAI
+ */
+static struct mca_cluster *mca_dai_to_cluster(struct snd_soc_dai *dai)
+{
+	struct mca_data *mca = snd_soc_dai_get_drvdata(dai);
+	/*
+	 * FE DAIs are         0 ... nclusters - 1
+	 * BE DAIs are nclusters ... 2*nclusters - 1
+	 */
+	int cluster_no = dai->id % mca->nclusters;
+
+	return &mca->clusters[cluster_no];
+}
+
+/* called before PCM trigger */
+static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
+				 struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+	int serdes_conf =
+		serdes_unit + (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_RST);
+		mca_modify(cl, serdes_conf, SERDES_CONF_SOME_RST,
+			   SERDES_CONF_SOME_RST);
+		readl_relaxed(cl->base + serdes_conf);
+		mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
+		WARN_ON(readl_relaxed(cl->base + REG_SERDES_STATUS) &
+			SERDES_STATUS_RST);
+		break;
+	default:
+		break;
+	}
+}
+
+static int mca_fe_trigger(struct snd_pcm_substream *substream, int cmd,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	int serdes_unit = is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN | SERDES_STATUS_RST,
+			   SERDES_STATUS_EN);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+			   SERDES_STATUS_EN, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mca_fe_enable_clocks(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	int ret;
+
+	ret = clk_prepare_enable(cl->clk_parent);
+	if (ret) {
+		dev_err(mca->dev,
+			"cluster %d: unable to enable clock parent: %d\n",
+			cl->no, ret);
+		return ret;
+	}
+
+	/*
+	 * We can't power up the device earlier than this because
+	 * the power state driver would error out on seeing the device
+	 * as clock-gated.
+	 */
+	cl->pd_link = device_link_add(mca->dev, cl->pd_dev,
+				      DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					      DL_FLAG_RPM_ACTIVE);
+	if (!cl->pd_link) {
+		dev_err(mca->dev,
+			"cluster %d: unable to prop-up power domain\n", cl->no);
+		clk_disable_unprepare(cl->clk_parent);
+		return -EINVAL;
+	}
+
+	writel_relaxed(cl->no + 1, cl->base + REG_SYNCGEN_MCLK_SEL);
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN,
+		   SYNCGEN_STATUS_EN);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, STATUS_MCLK_EN);
+
+	return 0;
+}
+
+static void mca_fe_disable_clocks(struct mca_cluster *cl)
+{
+	mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN, 0);
+	mca_modify(cl, REG_STATUS, STATUS_MCLK_EN, 0);
+
+	device_link_del(cl->pd_link);
+	clk_disable_unprepare(cl->clk_parent);
+}
+
+static bool mca_fe_clocks_in_use(struct mca_cluster *cl)
+{
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *be_cl;
+	int stream, i;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		be_cl = &mca->clusters[i];
+
+		if (be_cl->port_driver != cl->no)
+			continue;
+
+		for_each_pcm_streams(stream)
+			if (be_cl->clocks_in_use[stream])
+				return true;
+	}
+	return false;
+}
+
+static int mca_be_prepare(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+	int ret;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+
+	/*
+	 * Typically the CODECs we are paired with will require clocks
+	 * to be present at time of unmute with the 'mute_stream' op
+	 * or at time of DAPM widget power-up. We need to enable clocks
+	 * here at the latest (frontend prepare would be too late).
+	 */
+	if (!mca_fe_clocks_in_use(fe_cl)) {
+		ret = mca_fe_enable_clocks(fe_cl);
+		if (ret < 0)
+			return ret;
+	}
+
+	cl->clocks_in_use[substream->stream] = true;
+
+	return 0;
+}
+
+static int mca_be_hw_free(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct mca_cluster *fe_cl;
+
+	if (cl->port_driver < 0)
+		return -EINVAL;
+
+	fe_cl = &mca->clusters[cl->port_driver];
+	if (!mca_fe_clocks_in_use(fe_cl))
+		return 0; /* Nothing to do */
+
+	cl->clocks_in_use[substream->stream] = false;
+
+	if (!mca_fe_clocks_in_use(fe_cl))
+		mca_fe_disable_clocks(fe_cl);
+
+	return 0;
+}
+
+static unsigned int mca_crop_mask(unsigned int mask, int nchans)
+{
+	while (hweight32(mask) > nchans)
+		mask &= ~(1 << __fls(mask));
+
+	return mask;
+}
+
+static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
+				unsigned int mask, int slots, int nchans,
+				int slot_width, bool is_tx, int port)
+{
+	__iomem void *serdes_base = cl->base + serdes_unit;
+	u32 serdes_conf, serdes_conf_mask;
+
+	serdes_conf_mask = SERDES_CONF_WIDTH_MASK | SERDES_CONF_NCHANS;
+	serdes_conf = FIELD_PREP(SERDES_CONF_NCHANS, max(slots, 1) - 1);
+	switch (slot_width) {
+	case 16:
+		serdes_conf |= SERDES_CONF_WIDTH_16BIT;
+		break;
+	case 20:
+		serdes_conf |= SERDES_CONF_WIDTH_20BIT;
+		break;
+	case 24:
+		serdes_conf |= SERDES_CONF_WIDTH_24BIT;
+		break;
+	case 32:
+		serdes_conf |= SERDES_CONF_WIDTH_32BIT;
+		break;
+	default:
+		goto err;
+	}
+
+	serdes_conf_mask |= SERDES_CONF_SYNC_SEL;
+	serdes_conf |= FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1);
+
+	if (is_tx) {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_UNK3;
+	} else {
+		serdes_conf_mask |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+				    SERDES_CONF_UNK3 |
+				    SERDES_CONF_NO_DATA_FEEDBACK;
+		serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 |
+			       SERDES_CONF_NO_DATA_FEEDBACK;
+	}
+
+	mca_modify(cl,
+		   serdes_unit +
+			   (is_tx ? REG_TX_SERDES_CONF : REG_RX_SERDES_CONF),
+		   serdes_conf_mask, serdes_conf);
+
+	if (is_tx) {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0x8);
+		writel_relaxed(~((u32)mask),
+			       serdes_base + REG_TX_SERDES_SLOTMASK + 0xc);
+	} else {
+		writel_relaxed(0xffffffff,
+			       serdes_base + REG_RX_SERDES_SLOTMASK);
+		writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
+			       serdes_base + REG_RX_SERDES_SLOTMASK + 0x4);
+		writel_relaxed(1 << port,
+			       serdes_base + REG_RX_SERDES_PORT);
+	}
+
+	return 0;
+
+err:
+	dev_err(cl->host->dev,
+		"unsupported SERDES configuration requested (mask=0x%x slots=%d slot_width=%d)\n",
+		mask, slots, slot_width);
+	return -EINVAL;
+}
+
+static int mca_fe_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+			       unsigned int rx_mask, int slots, int slot_width)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->tdm_slots = slots;
+	cl->tdm_slot_width = slot_width;
+	cl->tdm_tx_mask = tx_mask;
+	cl->tdm_rx_mask = rx_mask;
+
+	return 0;
+}
+
+static int mca_fe_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	bool fpol_inv = false;
+	u32 serdes_conf = 0;
+	u32 bitstart;
+
+	if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) !=
+	    SND_SOC_DAIFMT_CBC_CFC)
+		goto err;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		fpol_inv = 0;
+		bitstart = 1;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		fpol_inv = 1;
+		bitstart = 0;
+		break;
+	default:
+		goto err;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_IF:
+	case SND_SOC_DAIFMT_IB_IF:
+		fpol_inv ^= 1;
+		break;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+	case SND_SOC_DAIFMT_NB_IF:
+		serdes_conf |= SERDES_CONF_BCLK_POL;
+		break;
+	}
+
+	if (!fpol_inv)
+		goto err;
+
+	mca_modify(cl, CLUSTER_TX_OFF + REG_TX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	mca_modify(cl, CLUSTER_RX_OFF + REG_RX_SERDES_CONF,
+		   SERDES_CONF_BCLK_POL, serdes_conf);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_TX_OFF + REG_TX_SERDES_BITSTART);
+	writel_relaxed(bitstart,
+		       cl->base + CLUSTER_RX_OFF + REG_RX_SERDES_BITSTART);
+
+	return 0;
+
+err:
+	dev_err(mca->dev, "unsupported DAI format (0x%x) requested\n", fmt);
+	return -EINVAL;
+}
+
+static int mca_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->bclk_ratio = ratio;
+
+	return 0;
+}
+
+static int mca_fe_get_port(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *be;
+	struct snd_soc_dpcm *dpcm;
+
+	be = NULL;
+	for_each_dpcm_be(fe, substream->stream, dpcm) {
+		be = dpcm->be;
+		break;
+	}
+
+	if (!be)
+		return -EINVAL;
+
+	return mca_dai_to_cluster(asoc_rtd_to_cpu(be, 0))->no;
+}
+
+static int mca_fe_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_data *mca = cl->host;
+	struct device *dev = mca->dev;
+	unsigned int samp_rate = params_rate(params);
+	bool is_tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	bool refine_tdm = false;
+	unsigned long bclk_ratio;
+	unsigned int tdm_slots, tdm_slot_width, tdm_mask;
+	u32 regval, pad;
+	int ret, port, nchans_ceiled;
+
+	if (!cl->tdm_slot_width) {
+		/*
+		 * We were not given TDM settings from above, set initial
+		 * guesses which will later be refined.
+		 */
+		tdm_slot_width = params_width(params);
+		tdm_slots = params_channels(params);
+		refine_tdm = true;
+	} else {
+		tdm_slot_width = cl->tdm_slot_width;
+		tdm_slots = cl->tdm_slots;
+		tdm_mask = is_tx ? cl->tdm_tx_mask : cl->tdm_rx_mask;
+	}
+
+	if (cl->bclk_ratio)
+		bclk_ratio = cl->bclk_ratio;
+	else
+		bclk_ratio = tdm_slot_width * tdm_slots;
+
+	if (refine_tdm) {
+		int nchannels = params_channels(params);
+
+		if (nchannels > 2) {
+			dev_err(dev, "missing TDM for stream with two or more channels\n");
+			return -EINVAL;
+		}
+
+		if ((bclk_ratio % nchannels) != 0) {
+			dev_err(dev, "BCLK ratio (%ld) not divisible by no. of channels (%d)\n",
+				bclk_ratio, nchannels);
+			return -EINVAL;
+		}
+
+		tdm_slot_width = bclk_ratio / nchannels;
+
+		if (tdm_slot_width > 32 && nchannels == 1)
+			tdm_slot_width = 32;
+
+		if (tdm_slot_width < params_width(params)) {
+			dev_err(dev, "TDM slots too narrow (tdm=%d params=%d)\n",
+				tdm_slot_width, params_width(params));
+			return -EINVAL;
+		}
+
+		tdm_mask = (1 << tdm_slots) - 1;
+	}
+
+	port = mca_fe_get_port(substream);
+	if (port < 0)
+		return port;
+
+	ret = mca_configure_serdes(cl, is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF,
+				   tdm_mask, tdm_slots, params_channels(params),
+				   tdm_slot_width, is_tx, port);
+	if (ret)
+		return ret;
+
+	pad = 32 - params_width(params);
+
+	/*
+	 * TODO: Here the register semantics aren't clear.
+	 */
+	nchans_ceiled = min_t(int, params_channels(params), 4);
+	regval = FIELD_PREP(DMA_ADAPTER_NCHANS, nchans_ceiled) |
+		 FIELD_PREP(DMA_ADAPTER_TX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_RX_NCHANS, 0x2) |
+		 FIELD_PREP(DMA_ADAPTER_TX_LSB_PAD, pad) |
+		 FIELD_PREP(DMA_ADAPTER_RX_MSB_PAD, pad);
+
+#ifndef USE_RXB_FOR_CAPTURE
+	writel_relaxed(regval, mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+#else
+	if (is_tx)
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_A(cl->no));
+	else
+		writel_relaxed(regval,
+			       mca->switch_base + REG_DMA_ADAPTER_B(cl->no));
+#endif
+
+	if (!mca_fe_clocks_in_use(cl)) {
+		/*
+		 * Set up FSYNC duty cycle as even as possible.
+		 */
+		writel_relaxed((bclk_ratio / 2) - 1,
+			       cl->base + REG_SYNCGEN_HI_PERIOD);
+		writel_relaxed(((bclk_ratio + 1) / 2) - 1,
+			       cl->base + REG_SYNCGEN_LO_PERIOD);
+		writel_relaxed(FIELD_PREP(MCLK_CONF_DIV, 0x1),
+			       cl->base + REG_MCLK_CONF);
+
+		ret = clk_set_rate(cl->clk_parent, bclk_ratio * samp_rate);
+		if (ret) {
+			dev_err(mca->dev, "cluster %d: unable to set clock parent: %d\n",
+				cl->no, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops mca_fe_ops = {
+	.set_fmt = mca_fe_set_fmt,
+	.set_bclk_ratio = mca_set_bclk_ratio,
+	.set_tdm_slot = mca_fe_set_tdm_slot,
+	.hw_params = mca_fe_hw_params,
+	.trigger = mca_fe_trigger,
+};
+
+static bool mca_be_started(struct mca_cluster *cl)
+{
+	int stream;
+
+	for_each_pcm_streams(stream)
+		if (cl->port_started[stream])
+			return true;
+	return false;
+}
+
+static int mca_be_startup(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *be = asoc_substream_to_rtd(substream);
+	struct snd_soc_pcm_runtime *fe;
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+	struct mca_cluster *fe_cl;
+	struct mca_data *mca = cl->host;
+	struct snd_soc_dpcm *dpcm;
+
+	fe = NULL;
+
+	for_each_dpcm_fe(be, substream->stream, dpcm) {
+		if (fe && dpcm->fe != fe) {
+			dev_err(mca->dev, "many FE per one BE unsupported\n");
+			return -EINVAL;
+		}
+
+		fe = dpcm->fe;
+	}
+
+	if (!fe)
+		return -EINVAL;
+
+	fe_cl = mca_dai_to_cluster(asoc_rtd_to_cpu(fe, 0));
+
+	if (mca_be_started(cl)) {
+		/*
+		 * Port is already started in the other direction.
+		 * Make sure there isn't a conflict with another cluster
+		 * driving the port.
+		 */
+		if (cl->port_driver != fe_cl->no)
+			return -EINVAL;
+
+		cl->port_started[substream->stream] = true;
+		return 0;
+	}
+
+	writel_relaxed(PORT_ENABLES_CLOCKS | PORT_ENABLES_TX_DATA,
+		       cl->base + REG_PORT_ENABLES);
+	writel_relaxed(FIELD_PREP(PORT_CLOCK_SEL, fe_cl->no + 1),
+		       cl->base + REG_PORT_CLOCK_SEL);
+	writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no),
+		       cl->base + REG_PORT_DATA_SEL);
+	cl->port_driver = fe_cl->no;
+	cl->port_started[substream->stream] = true;
+
+	return 0;
+}
+
+static void mca_be_shutdown(struct snd_pcm_substream *substream,
+			    struct snd_soc_dai *dai)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(dai);
+
+	cl->port_started[substream->stream] = false;
+
+	if (!mca_be_started(cl)) {
+		/*
+		 * Were we the last direction to shutdown?
+		 * Turn off the lights.
+		 */
+		writel_relaxed(0, cl->base + REG_PORT_ENABLES);
+		writel_relaxed(0, cl->base + REG_PORT_DATA_SEL);
+		cl->port_driver = -1;
+	}
+}
+
+static const struct snd_soc_dai_ops mca_be_ops = {
+	.prepare = mca_be_prepare,
+	.hw_free = mca_be_hw_free,
+	.startup = mca_be_startup,
+	.shutdown = mca_be_shutdown,
+};
+
+static int mca_set_runtime_hwparams(struct snd_soc_component *component,
+				    struct snd_pcm_substream *substream,
+				    struct dma_chan *chan)
+{
+	struct device *dma_dev = chan->device->dev;
+	struct snd_dmaengine_dai_dma_data dma_data = {};
+	int ret;
+
+	struct snd_pcm_hardware hw;
+
+	memset(&hw, 0, sizeof(hw));
+
+	hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+		  SNDRV_PCM_INFO_INTERLEAVED;
+	hw.periods_min = 2;
+	hw.periods_max = UINT_MAX;
+	hw.period_bytes_min = 256;
+	hw.period_bytes_max = dma_get_max_seg_size(dma_dev);
+	hw.buffer_bytes_max = SIZE_MAX;
+	hw.fifo_size = 16;
+
+	ret = snd_dmaengine_pcm_refine_runtime_hwparams(substream, &dma_data,
+							&hw, chan);
+
+	if (ret)
+		return ret;
+
+	return snd_soc_set_runtime_hwparams(substream, &hw);
+}
+
+static int mca_pcm_open(struct snd_soc_component *component,
+			struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	struct dma_chan *chan = cl->dma_chans[substream->stream];
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	ret = mca_set_runtime_hwparams(component, substream, chan);
+	if (ret)
+		return ret;
+
+	return snd_dmaengine_pcm_open(substream, chan);
+}
+
+static int mca_hw_params(struct snd_soc_component *component,
+			 struct snd_pcm_substream *substream,
+			 struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
+	struct dma_slave_config slave_config;
+	int ret;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	memset(&slave_config, 0, sizeof(slave_config));
+	ret = snd_hwparams_to_dma_slave_config(substream, params,
+					       &slave_config);
+	if (ret < 0)
+		return ret;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		slave_config.dst_port_window_size =
+			min_t(u32, params_channels(params), 4);
+	else
+		slave_config.src_port_window_size =
+			min_t(u32, params_channels(params), 4);
+
+	return dmaengine_slave_config(chan, &slave_config);
+}
+
+static int mca_close(struct snd_soc_component *component,
+		     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	return snd_dmaengine_pcm_close(substream);
+}
+
+static int mca_trigger(struct snd_soc_component *component,
+		       struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	/*
+	 * Before we do the PCM trigger proper, insert an opportunity
+	 * to reset the frontend's SERDES.
+	 */
+	mca_fe_early_trigger(substream, cmd, asoc_rtd_to_cpu(rtd, 0));
+
+	return snd_dmaengine_pcm_trigger(substream, cmd);
+}
+
+static snd_pcm_uframes_t mca_pointer(struct snd_soc_component *component,
+				     struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+
+	if (rtd->dai_link->no_pcm)
+		return -ENOTSUPP;
+
+	return snd_dmaengine_pcm_pointer(substream);
+}
+
+static int mca_pcm_new(struct snd_soc_component *component,
+		       struct snd_soc_pcm_runtime *rtd)
+{
+	struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+	unsigned int i;
+
+	if (rtd->dai_link->no_pcm)
+		return 0;
+
+	for_each_pcm_streams(i) {
+		struct snd_pcm_substream *substream =
+			rtd->pcm->streams[i].substream;
+		struct dma_chan *chan = cl->dma_chans[i];
+
+		if (!substream)
+			continue;
+
+		if (!chan) {
+			dev_err(component->dev, "missing DMA channel for stream %d on SERDES %d\n",
+				i, cl->no);
+			return -EINVAL;
+		}
+
+		snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV_IRAM,
+					   chan->device->dev, 512 * 1024 * 6,
+					   SIZE_MAX);
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_component_driver mca_component = {
+	.name = "apple-mca",
+	.open = mca_pcm_open,
+	.close = mca_close,
+	.hw_params = mca_hw_params,
+	.trigger = mca_trigger,
+	.pointer = mca_pointer,
+	.pcm_construct = mca_pcm_new,
+};
+
+static void apple_mca_release(struct mca_data *mca)
+{
+	int i, stream;
+
+	for (i = 0; i < mca->nclusters; i++) {
+		struct mca_cluster *cl = &mca->clusters[i];
+
+		for_each_pcm_streams(stream) {
+			if (IS_ERR_OR_NULL(cl->dma_chans[stream]))
+				continue;
+
+			dma_release_channel(cl->dma_chans[stream]);
+		}
+
+		if (!IS_ERR_OR_NULL(cl->clk_parent))
+			clk_put(cl->clk_parent);
+
+		if (!IS_ERR_OR_NULL(cl->pd_dev))
+			dev_pm_domain_detach(cl->pd_dev, true);
+	}
+
+	if (mca->pd_link)
+		device_link_del(mca->pd_link);
+
+	if (!IS_ERR_OR_NULL(mca->pd_dev))
+		dev_pm_domain_detach(mca->pd_dev, true);
+
+	reset_control_assert(mca->rstc);
+}
+
+static int apple_mca_probe(struct platform_device *pdev)
+{
+	struct mca_data *mca;
+	struct mca_cluster *clusters;
+	struct snd_soc_dai_driver *dai_drivers;
+	struct resource *res;
+	void __iomem *base;
+	int nclusters;
+	int ret, i;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	if (resource_size(res) < CLUSTER_STRIDE)
+		return -EINVAL;
+	nclusters = (resource_size(res) - CLUSTER_STRIDE) / CLUSTER_STRIDE + 1;
+
+	mca = devm_kzalloc(&pdev->dev, struct_size(mca, clusters, nclusters),
+			   GFP_KERNEL);
+	if (!mca)
+		return -ENOMEM;
+	mca->dev = &pdev->dev;
+	mca->nclusters = nclusters;
+	platform_set_drvdata(pdev, mca);
+	clusters = mca->clusters;
+
+	mca->switch_base =
+		devm_platform_ioremap_resource_byname(pdev, "switch");
+	if (IS_ERR(mca->switch_base))
+		return PTR_ERR(mca->switch_base);
+
+	mca->rstc = devm_reset_control_get_shared(&pdev->dev, NULL);
+	if (IS_ERR(mca->rstc)) {
+		dev_dbg(&pdev->dev, "couldn't obtain reset control: %pe\n", mca->rstc);
+		mca->rstc = NULL;
+	}
+
+	dai_drivers = devm_kzalloc(
+		&pdev->dev, sizeof(*dai_drivers) * 2 * nclusters, GFP_KERNEL);
+	if (!dai_drivers)
+		return -ENOMEM;
+
+	mca->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, 0);
+	if (IS_ERR(mca->pd_dev))
+		return -EINVAL;
+
+	mca->pd_link = device_link_add(&pdev->dev, mca->pd_dev,
+				       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+					       DL_FLAG_RPM_ACTIVE);
+	if (!mca->pd_link) {
+		ret = -EINVAL;
+		/* Prevent an unbalanced reset assert */
+		mca->rstc = NULL;
+		goto err_release;
+	}
+
+	reset_control_deassert(mca->rstc);
+
+	for (i = 0; i < nclusters; i++) {
+		struct mca_cluster *cl = &clusters[i];
+		struct snd_soc_dai_driver *fe =
+			&dai_drivers[mca->nclusters + i];
+		struct snd_soc_dai_driver *be = &dai_drivers[i];
+		int stream;
+
+		cl->host = mca;
+		cl->no = i;
+		cl->base = base + CLUSTER_STRIDE * i;
+		cl->port_driver = -1;
+		cl->clk_parent = of_clk_get(pdev->dev.of_node, i);
+		if (IS_ERR(cl->clk_parent)) {
+			dev_err(&pdev->dev, "unable to obtain clock %d: %ld\n",
+				i, PTR_ERR(cl->clk_parent));
+			ret = PTR_ERR(cl->clk_parent);
+			goto err_release;
+		}
+		cl->pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, i + 1);
+		if (IS_ERR(cl->pd_dev)) {
+			dev_err(&pdev->dev,
+				"unable to obtain cluster %d PD: %ld\n", i,
+				PTR_ERR(cl->pd_dev));
+			ret = PTR_ERR(cl->pd_dev);
+			goto err_release;
+		}
+
+		for_each_pcm_streams(stream) {
+			struct dma_chan *chan;
+			bool is_tx = (stream == SNDRV_PCM_STREAM_PLAYBACK);
+#ifndef USE_RXB_FOR_CAPTURE
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%da",
+						    i);
+#else
+			char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+						    is_tx ? "tx%da" : "rx%db",
+						    i);
+#endif
+
+			chan = of_dma_request_slave_channel(pdev->dev.of_node,
+							    name);
+			if (IS_ERR(chan)) {
+				if (PTR_ERR(chan) != -EPROBE_DEFER)
+					dev_err(&pdev->dev,
+						"no %s DMA channel: %ld\n",
+						name, PTR_ERR(chan));
+
+				ret = PTR_ERR(chan);
+				goto err_release;
+			}
+
+			cl->dma_chans[stream] = chan;
+		}
+
+		fe->id = i;
+		fe->name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-pcm-%d", i);
+		if (!fe->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		fe->ops = &mca_fe_ops;
+		fe->playback.channels_min = 1;
+		fe->playback.channels_max = 32;
+		fe->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->playback.formats = APPLE_MCA_FMTBITS;
+		fe->capture.channels_min = 1;
+		fe->capture.channels_max = 32;
+		fe->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		fe->capture.formats = APPLE_MCA_FMTBITS;
+		fe->symmetric_rate = 1;
+
+		fe->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d TX", i);
+		fe->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "PCM%d RX", i);
+
+		if (!fe->playback.stream_name || !fe->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+
+		be->id = i + nclusters;
+		be->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-i2s-%d", i);
+		if (!be->name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+		be->ops = &mca_be_ops;
+		be->playback.channels_min = 1;
+		be->playback.channels_max = 32;
+		be->playback.rates = SNDRV_PCM_RATE_8000_192000;
+		be->playback.formats = APPLE_MCA_FMTBITS;
+		be->capture.channels_min = 1;
+		be->capture.channels_max = 32;
+		be->capture.rates = SNDRV_PCM_RATE_8000_192000;
+		be->capture.formats = APPLE_MCA_FMTBITS;
+
+		be->playback.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d TX", i);
+		be->capture.stream_name =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "I2S%d RX", i);
+		if (!be->playback.stream_name || !be->capture.stream_name) {
+			ret = -ENOMEM;
+			goto err_release;
+		}
+	}
+
+	ret = devm_snd_soc_register_component(&pdev->dev, &mca_component,
+					      dai_drivers, nclusters * 2);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to register ASoC component: %d\n",
+			ret);
+		goto err_release;
+	}
+
+	return 0;
+
+err_release:
+	apple_mca_release(mca);
+	return ret;
+}
+
+static int apple_mca_remove(struct platform_device *pdev)
+{
+	struct mca_data *mca = platform_get_drvdata(pdev);
+
+	apple_mca_release(mca);
+	return 0;
+}
+
+static const struct of_device_id apple_mca_of_match[] = {
+	{ .compatible = "apple,mca", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, apple_mca_of_match);
+
+static struct platform_driver apple_mca_driver = {
+	.driver = {
+		.name = "apple-mca",
+		.owner = THIS_MODULE,
+		.of_match_table = apple_mca_of_match,
+	},
+	.probe = apple_mca_probe,
+	.remove = apple_mca_remove,
+};
+module_platform_driver(apple_mca_driver);
+
+MODULE_AUTHOR("Martin Povišer <povik+lin@cutebit.org>");
+MODULE_DESCRIPTION("ASoC Apple MCA driver");
+MODULE_LICENSE("GPL");
-- 
2.33.0


^ permalink raw reply related	[relevance 5%]

* [PATCH RFC 1/4] dt-bindings: input: touchscreen: Add Z2 controller bindings.
@ 2023-02-24 10:20  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-02-24 10:20 UTC (permalink / raw)
  To: Hector Martin, Sven Peter, Alyssa Rosenzweig, Dmitry Torokhov,
	Rob Herring, Krzysztof Kozlowski, -, Henrik Rydberg
  Cc: linux-arm-kernel, linux-input, devicetree, linux-kernel,
	Sasha Finkelstein

Add bindings for touchscreen controllers attached using the Z2 protocol.
Those are present in most Apple devices.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
---
 .../input/touchscreen/apple,z2-touchscreen.yaml    | 81 ++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/apple,z2-touchscreen.yaml b/Documentation/devicetree/bindings/input/touchscreen/apple,z2-touchscreen.yaml
new file mode 100644
index 000000000000..695594494b1e
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/apple,z2-touchscreen.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/apple,z2-touchscreen.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple touchscreens attached using the Z2 protocol.
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: A series of touschscreen controllers used in Apple products.
+
+allOf:
+  - $ref: touchscreen.yaml#
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+  compatible:
+    const: apple,z2-touchscreen
+
+  reg:
+    maxItems: 1
+
+  interrupts-extended:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+  cs-gpios:
+    maxItems: 1
+
+  firmware-name:
+    maxItems: 1
+
+  apple,z2-device-name:
+    description: The name to be used for the input device
+    $ref: /schemas/types.yaml#/definitions/string
+
+  touchscreen-size-x: true
+  touchscreen-size-y: true
+  spi-max-frequency: true
+
+required:
+  - compatible
+  - interrupts-extended
+  - reset-gpios
+  - cs-gpios
+  - firmware-name
+  - apple,z2-device-name
+  - touchscreen-size-x
+  - touchscreen-size-y
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            touchscreen@0 {
+                    compatible = "apple,z2-touchscreen";
+                    reg = <0>;
+                    spi-max-frequency = <11500000>;
+                    reset-gpios = <&pinctrl_ap 139 0>;
+                    cs-gpios = <&pinctrl_ap 109 0>;
+                    interrupts-extended = <&pinctrl_ap 194 IRQ_TYPE_EDGE_FALLING>;
+                    firmware-name = "apple/dfrmtfw-j293.bin";
+                    touchscreen-size-x = <23045>;
+                    touchscreen-size-y = <640>;
+                    apple,z2-device-name = "MacBookPro17,1 Touch Bar";
+            };
+    };
+
+...

-- 
Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [RFC PATCH v2 4/4] tsm: Allow for extending and reading configured RTMRs
  @ 2024-01-28 21:25  5% ` Samuel Ortiz
  0 siblings, 0 replies; 200+ results
From: Samuel Ortiz @ 2024-01-28 21:25 UTC (permalink / raw)
  To: Dan Williams
  Cc: Samuel Ortiz, Kuppuswamy Sathyanarayanan, Qinkun Bao, Yao, Jiewen,
	Xing, Cedric, Dionna Amalie Glaze, biao.lu, linux-coco,
	linux-integrity, linux-kernel

The whole purpose of TSM supported RTMRs is for userspace to extend them
with runtime measurements and to read them back.

This can be done through a binary configfs attribute for each RTMR:

rtmr0=/sys/kernel/config/tsm/rtmrs/rtmr0
mkdir $rtmr0
echo 0 > $rtmr0/index
dd if=software_layer_digest > $rtmr0/digest
hexdump $rtmr0/digest

An RTMR digest can not be extended or read before the RTMR is configured
by assigning it an index.

Signed-off-by: Samuel Ortiz <sameo@rivosinc.com>
---
 Documentation/ABI/testing/configfs-tsm | 11 +++++
 drivers/virt/coco/Kconfig              |  1 +
 drivers/virt/coco/tsm.c                | 58 ++++++++++++++++++++++++++
 3 files changed, 70 insertions(+)

diff --git a/Documentation/ABI/testing/configfs-tsm b/Documentation/ABI/testing/configfs-tsm
index 5d20a872475e..dc5c68a49625 100644
--- a/Documentation/ABI/testing/configfs-tsm
+++ b/Documentation/ABI/testing/configfs-tsm
@@ -81,6 +81,17 @@ Description:
 		(RO) Indicates the minimum permissible value that can be written
 		to @privlevel.
 
+What:		/sys/kernel/config/tsm/rtmrs/$name/digest
+Date:		January, 2024
+KernelVersion:	v6.8
+Contact:	linux-coco@lists.linux.dev
+Description:
+		(RW) The value in this attribute is the Runtime Measurement
+		Register (RTMR) digest. Callers can extend this digest with
+		additional hashes by writing into it. Binary blobs written to
+		this attribute must be of the exact length used by the hash
+		algorithm for this RTMR.
+
 What:		/sys/kernel/config/tsm/rtmrs/$name/index
 Date:		January, 2024
 KernelVersion:	v6.8
diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig
index 87d142c1f932..5d924bae1ed8 100644
--- a/drivers/virt/coco/Kconfig
+++ b/drivers/virt/coco/Kconfig
@@ -5,6 +5,7 @@
 
 config TSM_REPORTS
 	select CONFIGFS_FS
+	select CRYPTO_HASH_INFO
 	tristate
 
 source "drivers/virt/coco/efi_secret/Kconfig"
diff --git a/drivers/virt/coco/tsm.c b/drivers/virt/coco/tsm.c
index d03cf5173bc9..b4f8cf6ca149 100644
--- a/drivers/virt/coco/tsm.c
+++ b/drivers/virt/coco/tsm.c
@@ -551,6 +551,63 @@ static struct configfs_attribute *tsm_rtmr_attrs[] = {
 	NULL,
 };
 
+static ssize_t tsm_rtmr_digest_read(struct config_item *cfg, void *buf,
+				    size_t count)
+{
+	struct tsm_rtmr_state *rtmr_state = to_tsm_rtmr_state(cfg);
+	int rc, digest_size = hash_digest_size[rtmr_state->alg];
+
+	/* configfs is asking for the digest size */
+	if (!buf)
+		return digest_size;
+
+	if (!is_rtmr_configured(rtmr_state))
+		return -ENXIO;
+
+	if (count > TSM_DIGEST_MAX || count < digest_size)
+		return -EINVAL;
+
+	/* Read from the cached digest */
+	if (rtmr_state->cached_digest) {
+		memcpy(buf, rtmr_state->digest, count);
+		return digest_size;
+	}
+
+	/* Slow path, this RTMR got extended */
+	guard(rwsem_write)(&tsm_rwsem);
+	rc = tsm_rtmr_read(&provider, rtmr_state->index, buf, count);
+	if (rc < 0)
+		return rc;
+
+	/* Update the cached digest */
+	memcpy(rtmr_state->digest, buf, count);
+	rtmr_state->cached_digest = true;
+
+	return rc;
+}
+
+static ssize_t tsm_rtmr_digest_write(struct config_item *cfg,
+				     const void *buf, size_t count)
+{
+	struct tsm_rtmr_state *rtmr_state = to_tsm_rtmr_state(cfg);
+
+	if (!is_rtmr_configured(rtmr_state))
+		return -ENXIO;
+
+	if (count > TSM_DIGEST_MAX || count < hash_digest_size[rtmr_state->alg])
+		return -EINVAL;
+
+	guard(rwsem_write)(&tsm_rwsem);
+	rtmr_state->cached_digest = false;
+	return tsm_rtmr_extend(&provider, rtmr_state->index, buf, count);
+}
+CONFIGFS_BIN_ATTR(tsm_rtmr_, digest, NULL, TSM_DIGEST_MAX);
+
+static struct configfs_bin_attribute *tsm_rtmr_bin_attrs[] = {
+	&tsm_rtmr_attr_digest,
+	NULL,
+};
+
 static void tsm_rtmr_item_release(struct config_item *cfg)
 {
 	struct tsm_rtmr_state *state = to_tsm_rtmr_state(cfg);
@@ -564,6 +621,7 @@ static struct configfs_item_operations tsm_rtmr_item_ops = {
 
 const struct config_item_type tsm_rtmr_type = {
 	.ct_owner = THIS_MODULE,
+	.ct_bin_attrs = tsm_rtmr_bin_attrs,
 	.ct_attrs = tsm_rtmr_attrs,
 	.ct_item_ops = &tsm_rtmr_item_ops,
 };
-- 
2.42.0


^ permalink raw reply related	[relevance 5%]

* + mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice.patch added to mm-unstable branch
@ 2023-02-09 22:14  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2023-02-09 22:14 UTC (permalink / raw)
  To: mm-commits, corbet, sj, akpm


The patch titled
     Subject: mm/damon/Kconfig: add DAMON debugfs interface deprecation notice
has been added to the -mm mm-unstable branch.  Its filename is
     mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice.patch

This patch will later appear in the mm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: mm/damon/Kconfig: add DAMON debugfs interface deprecation notice
Date: Thu, 9 Feb 2023 19:20:08 +0000

DAMON debugfs interface has announced to be deprecated after >v5.15 LTS
kernel is released.  And, v6.1.y has announced to be an LTS[1].

Though the announcement was there for a while, some people might not
noticed that so far.  Also, some users could depend on it and have
problems at  movng to the alternative (DAMON sysfs interface).

For such cases, note DAMON debugfs interface as deprecated, and contacts
to ask helps on the Kconfig.

[1] https://git.kernel.org/pub/scm/docs/kernel/website.git/commit/?id=332e9121320bc7461b2d3a79665caf153e51732c

Link: https://lkml.kernel.org/r/20230209192009.7885-3-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 mm/damon/Kconfig |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

--- a/mm/damon/Kconfig~mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice
+++ a/mm/damon/Kconfig
@@ -60,7 +60,7 @@ config DAMON_SYSFS
 	  the interface for arbitrary data access monitoring.
 
 config DAMON_DBGFS
-	bool "DAMON debugfs interface"
+	bool "DAMON debugfs interface (DEPRECATED!)"
 	depends on DAMON_VADDR && DAMON_PADDR && DEBUG_FS
 	help
 	  This builds the debugfs interface for DAMON.  The user space admins
@@ -68,8 +68,9 @@ config DAMON_DBGFS
 
 	  If unsure, say N.
 
-	  This will be removed after >5.15.y LTS kernel is released, so users
-	  should move to the sysfs interface (DAMON_SYSFS).
+	  This is deprecated, so users should move to the sysfs interface
+	  (DAMON_SYSFS).  If you depend on this and cannot move, please report
+	  your usecase to damon@lists.linux.dev and linux-mm@kvack.org.
 
 config DAMON_DBGFS_KUNIT_TEST
 	bool "Test for damon debugfs interface" if !KUNIT_ALL_TESTS
_

Patches currently in -mm which might be from sj@kernel.org are

docs-admin-guide-mm-damon-usage-add-damon-debugfs-interface-deprecation-notice.patch
mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice.patch
mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message.patch


^ permalink raw reply	[relevance 5%]

* [RFC PATCH v2 2/6] coco/guest: Move shared guest CC infrastructure to drivers/virt/coco/guest/
    2024-04-12  8:52  5% ` [RFC PATCH v2 4/6] coco/tsm: Introduce a class device for TEE Security Managers Dan Williams
@ 2024-04-12  8:51  5% ` Dan Williams
  1 sibling, 0 replies; 200+ results
From: Dan Williams @ 2024-04-12  8:51 UTC (permalink / raw)
  To: linux-coco
  Cc: Wu Hao, Yilun Xu, Samuel Ortiz, Alexey Kardashevskiy,
	Tom Lendacky, bhelgaas, kevin.tian, gregkh, linux-pci, lukas

In preparation for creating a new drivers/virt/coco/host/ directory to
house shared host driver infrastructure for confidential computing, move
configfs-tsm to a guest/ sub-directory. The tsm.ko module is renamed to
tsm_reports.ko. The old tsm.ko module was only ever demand loaded by
kernel internal dependencies, so it should not affect existing userspace
module install scripts.

Cc: Wu Hao <hao.wu@intel.com>
Cc: Yilun Xu <yilun.xu@intel.com>
Cc: Samuel Ortiz <sameo@rivosinc.com>
Cc: Alexey Kardashevskiy <aik@amd.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 MAINTAINERS                             |    2 +-
 drivers/virt/coco/Kconfig               |    6 ++----
 drivers/virt/coco/Makefile              |    2 +-
 drivers/virt/coco/guest/Kconfig         |    7 +++++++
 drivers/virt/coco/guest/Makefile        |    2 ++
 drivers/virt/coco/guest/tsm_report.c    |    8 ++++----
 drivers/virt/coco/sev-guest/sev-guest.c |    4 ++--
 7 files changed, 19 insertions(+), 12 deletions(-)
 create mode 100644 drivers/virt/coco/guest/Kconfig
 create mode 100644 drivers/virt/coco/guest/Makefile
 rename drivers/virt/coco/{tsm.c => guest/tsm_report.c} (98%)

diff --git a/MAINTAINERS b/MAINTAINERS
index aa3b947fb080..65beba4e704a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22466,7 +22466,7 @@ M:	Dan Williams <dan.j.williams@intel.com>
 L:	linux-coco@lists.linux.dev
 S:	Maintained
 F:	Documentation/ABI/testing/configfs-tsm
-F:	drivers/virt/coco/tsm.c
+F:	drivers/virt/coco/guest/tsm_report.c
 F:	include/linux/tsm.h
 
 TTY LAYER AND SERIAL DRIVERS
diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig
index 87d142c1f932..7c41e0abd423 100644
--- a/drivers/virt/coco/Kconfig
+++ b/drivers/virt/coco/Kconfig
@@ -3,12 +3,10 @@
 # Confidential computing related collateral
 #
 
-config TSM_REPORTS
-	select CONFIGFS_FS
-	tristate
-
 source "drivers/virt/coco/efi_secret/Kconfig"
 
 source "drivers/virt/coco/sev-guest/Kconfig"
 
 source "drivers/virt/coco/tdx-guest/Kconfig"
+
+source "drivers/virt/coco/guest/Kconfig"
diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile
index 18c1aba5edb7..621111811a76 100644
--- a/drivers/virt/coco/Makefile
+++ b/drivers/virt/coco/Makefile
@@ -2,7 +2,7 @@
 #
 # Confidential computing related collateral
 #
-obj-$(CONFIG_TSM_REPORTS)	+= tsm.o
 obj-$(CONFIG_EFI_SECRET)	+= efi_secret/
 obj-$(CONFIG_SEV_GUEST)		+= sev-guest/
 obj-$(CONFIG_INTEL_TDX_GUEST)	+= tdx-guest/
+obj-$(CONFIG_TSM_REPORTS)	+= guest/
diff --git a/drivers/virt/coco/guest/Kconfig b/drivers/virt/coco/guest/Kconfig
new file mode 100644
index 000000000000..ed9bafbdd854
--- /dev/null
+++ b/drivers/virt/coco/guest/Kconfig
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Confidential computing shared guest collateral
+#
+config TSM_REPORTS
+	select CONFIGFS_FS
+	tristate
diff --git a/drivers/virt/coco/guest/Makefile b/drivers/virt/coco/guest/Makefile
new file mode 100644
index 000000000000..1f5fad59fc96
--- /dev/null
+++ b/drivers/virt/coco/guest/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_TSM_REPORTS)	+= tsm_report.o
diff --git a/drivers/virt/coco/tsm.c b/drivers/virt/coco/guest/tsm_report.c
similarity index 98%
rename from drivers/virt/coco/tsm.c
rename to drivers/virt/coco/guest/tsm_report.c
index 6cb0a0e6783d..272077a02da5 100644
--- a/drivers/virt/coco/tsm.c
+++ b/drivers/virt/coco/guest/tsm_report.c
@@ -391,7 +391,7 @@ EXPORT_SYMBOL_GPL(tsm_report_unregister);
 
 static struct config_group *tsm_report_group;
 
-static int __init tsm_init(void)
+static int __init tsm_report_init(void)
 {
 	struct config_group *root = &tsm_configfs.su_group;
 	struct config_group *tsm;
@@ -412,14 +412,14 @@ static int __init tsm_init(void)
 
 	return 0;
 }
-module_init(tsm_init);
+module_init(tsm_report_init);
 
-static void __exit tsm_exit(void)
+static void __exit tsm_report_exit(void)
 {
 	configfs_unregister_default_group(tsm_report_group);
 	configfs_unregister_subsystem(&tsm_configfs);
 }
-module_exit(tsm_exit);
+module_exit(tsm_report_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Provide Trusted Security Module attestation reports via configfs");
diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
index ce60e3ce8aa3..dc0e3ad21cbf 100644
--- a/drivers/virt/coco/sev-guest/sev-guest.c
+++ b/drivers/virt/coco/sev-guest/sev-guest.c
@@ -892,7 +892,7 @@ static const struct tsm_report_ops sev_tsm_report_ops = {
 
 static void unregister_sev_tsm(void *data)
 {
-	tsm_report_unregister(&sev_tsm_ops);
+	tsm_report_unregister(&sev_tsm_report_ops);
 }
 
 static int __init sev_guest_probe(struct platform_device *pdev)
@@ -968,7 +968,7 @@ static int __init sev_guest_probe(struct platform_device *pdev)
 	snp_dev->input.resp_gpa = __pa(snp_dev->response);
 	snp_dev->input.data_gpa = __pa(snp_dev->certs_data);
 
-	ret = tsm_report_register(&sev_tsm_ops, snp_dev, &tsm_report_extra_type);
+	ret = tsm_report_register(&sev_tsm_report_ops, snp_dev, &tsm_report_extra_type);
 	if (ret)
 		goto e_free_cert_data;
 


^ permalink raw reply related	[relevance 5%]

* Re: [PATCH v1 2/3] landlock: Slightly improve documentation and fix spelling
  @ 2022-09-24 13:29  5%   ` Bagas Sanjaya
  0 siblings, 0 replies; 200+ results
From: Bagas Sanjaya @ 2022-09-24 13:29 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: James Morris, Paul Moore, Serge E . Hallyn, Alejandro Colomar,
	Günther Noack, Jonathan Corbet, Konstantin Meskhidze,
	linux-doc, linux-security-module

[-- Attachment #1: Type: text/plain, Size: 23139 bytes --]

On Fri, Sep 23, 2022 at 05:42:06PM +0200, Mickaël Salaün wrote:
> Now that we have more than one ABI version, make limitation explanation
> more consistent by replacing "ABI 1" with "ABI < 2".  This also
> indicates which ABIs support such past limitation.
> 

Hi,

I think grammar and reference link on userspace documentation can be
improved, like:

---- >8 ----

diff --git a/Documentation/admin-guide/cgroup-v1/memory.rst b/Documentation/admin-guide/cgroup-v1/memory.rst
index 2cc502a75ef640..c49454900edb12 100644
--- a/Documentation/admin-guide/cgroup-v1/memory.rst
+++ b/Documentation/admin-guide/cgroup-v1/memory.rst
@@ -1,3 +1,5 @@
+.. _cgroup-v1-memory:
+
 ==========================
 Memory Resource Controller
 ==========================
diff --git a/Documentation/filesystems/overlayfs.rst b/Documentation/filesystems/overlayfs.rst
index 4c76fda076454c..dbeddb6851e6c9 100644
--- a/Documentation/filesystems/overlayfs.rst
+++ b/Documentation/filesystems/overlayfs.rst
@@ -3,6 +3,8 @@
 Written by: Neil Brown
 Please see MAINTAINERS file for where to send questions.
 
+.. _overlayfs:
+
 Overlay Filesystem
 ==================
 
diff --git a/Documentation/filesystems/sharedsubtree.rst b/Documentation/filesystems/sharedsubtree.rst
index d83395354250d9..cbc20658bd0c07 100644
--- a/Documentation/filesystems/sharedsubtree.rst
+++ b/Documentation/filesystems/sharedsubtree.rst
@@ -1,5 +1,7 @@
 .. SPDX-License-Identifier: GPL-2.0
 
+.. _shared-subtrees:
+
 ===============
 Shared Subtrees
 ===============
diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst
index 5dbd577b5f58b7..13a8db59b0c0e5 100644
--- a/Documentation/userspace-api/landlock.rst
+++ b/Documentation/userspace-api/landlock.rst
@@ -14,16 +14,18 @@ The goal of Landlock is to enable to restrict ambient rights (e.g. global
 filesystem access) for a set of processes.  Because Landlock is a stackable
 LSM, it makes possible to create safe security sandboxes as new security layers
 in addition to the existing system-wide access-controls. This kind of sandbox
-is expected to help mitigate the security impact of bugs or
-unexpected/malicious behaviors in user space applications.  Landlock empowers
-any process, including unprivileged ones, to securely restrict themselves.
+can help mitigating the security impact of bugs or unexpected/malicious
+behaviors in user space applications.  Landlock empowers any process, including
+unprivileged ones, to securely restrict themselves.
 
-We can quickly make sure that Landlock is enabled in the running system by
-looking for ``landlock: Up and running`` in kernel logs (as root): ``dmesg | 
-grep landlock || journalctl -kg landlock`` .  Developers can also easily check
-for Landlock support with a :ref:`related system call <landlock_abi_versions>`.
-If Landlock is not currently supported, we need to :ref:`configure the kernel
-appropriately <kernel_support>`.
+To check whether Landlock has been successfully enabled, look for
+``landlock: Up and running`` in kernel logs, which can be seen with (as root)::
+
+  dmesg | grep landlock || journalctl -kg landlock
+  
+Developers can also easily check for Landlock support with a
+:ref:`related system call <landlock_abi_versions>`. If Landlock is not
+currently supported, :ref:`the kernel needs to be configured <kernel_support>`.
 
 Landlock rules
 ==============
@@ -36,12 +38,12 @@ the thread enforcing it, and its future children.
 Defining and enforcing a security policy
 ----------------------------------------
 
-We first need to define the ruleset that will contain our rules.  For this
-example, the ruleset will contain rules that only allow read actions, but write
-actions will be denied.  The ruleset then needs to handle both of these kind of
+First, the ruleset that will contain rules needs to be defined. For this
+example, the ruleset will contain rules that only allow read actions (write
+actions will be denied). The ruleset then needs to handle both of these kind of
 actions.  This is required for backward and forward compatibility (i.e. the
 kernel and user space may not know each other's supported restrictions), hence
-the need to be explicit about the denied-by-default access rights.
+it is required to be explicit about the denied-by-default access rights.
 
 .. code-block:: c
 
@@ -63,14 +65,14 @@ the need to be explicit about the denied-by-default access rights.
             LANDLOCK_ACCESS_FS_REFER,
     };
 
-Because we may not know on which kernel version an application will be
-executed, it is safer to follow a best-effort security approach.  Indeed, we
-should try to protect users as much as possible whatever the kernel they are
-using.  To avoid binary enforcement (i.e. either all security features or
-none), we can leverage a dedicated Landlock command to get the current version
-of the Landlock ABI and adapt the handled accesses.  Let's check if we should
-remove the ``LANDLOCK_ACCESS_FS_REFER`` access right which is only supported
-starting with the second version of the ABI.
+Because it is unknown which kernel version an application will be executed,
+it is safer to follow a best-effort security approach. Indeed, users need to
+be protected as much as possible whatever the kernel they are
+using.  To avoid atomic enforcement situations (i.e. either all security
+features or none), a dedicated Landlock command to get the current version
+of the Landlock ABI can be used and adapt the handled accesses. Let's check if
+``LANDLOCK_ACCESS_FS_REFER`` access right (which is available since second
+ABI version) can be removed:
 
 .. code-block:: c
 
@@ -81,7 +83,7 @@ starting with the second version of the ABI.
         ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
     }
 
-This enables to create an inclusive ruleset that will contain our rules.
+This enables to create an inclusive ruleset that will contain the rules.
 
 .. code-block:: c
 
@@ -93,12 +95,11 @@ This enables to create an inclusive ruleset that will contain our rules.
         return 1;
     }
 
-We can now add a new rule to this ruleset thanks to the returned file
+Now a new rule to this ruleset can be added using the returned file
 descriptor referring to this ruleset.  The rule will only allow reading the
-file hierarchy ``/usr``.  Without another rule, write actions would then be
-denied by the ruleset.  To add ``/usr`` to the ruleset, we open it with the
-``O_PATH`` flag and fill the &struct landlock_path_beneath_attr with this file
-descriptor.
+file hierarchy ``/usr``. To add ``/usr`` to the ruleset, open the ruleset
+with the ``O_PATH`` flag and fill the struct landlock_path_beneath_attr with
+the descriptor:
 
 .. code-block:: c
 
@@ -125,15 +126,15 @@ descriptor.
         return 1;
     }
 
-It may also be required to create rules following the same logic as explained
-for the ruleset creation, by filtering access rights according to the Landlock
-ABI version.  In this example, this is not required because
-``LANDLOCK_ACCESS_FS_REFER`` is not allowed by any rule.
+It may also be required to add rules following the same logic as explained
+above, to filter access rights according to the Landlock ABI version.
+In this example, this is not required because ``LANDLOCK_ACCESS_FS_REFER``
+is not allowed by any rule.
 
-We now have a ruleset with one rule allowing read access to ``/usr`` while
+Now there is a ruleset with one rule allowing read access to ``/usr`` while
 denying all other handled accesses for the filesystem.  The next step is to
-restrict the current thread from gaining more privileges (e.g. thanks to a SUID
-binary).
+restrict the current thread from gaining more privileges (for example due
+to be run by setuid binary):
 
 .. code-block:: c
 
@@ -158,7 +159,7 @@ If the ``landlock_restrict_self`` system call succeeds, the current thread is
 now restricted and this policy will be enforced on all its subsequently created
 children as well.  Once a thread is landlocked, there is no way to remove its
 security policy; only adding more restrictions is allowed.  These threads are
-now in a new Landlock domain, merge of their parent one (if any) with the new
+now in a new Landlock domain, merging their parent one (if any) with the new
 ruleset.
 
 Full working code can be found in `samples/landlock/sandboxer.c`_.
@@ -166,24 +167,24 @@ Full working code can be found in `samples/landlock/sandboxer.c`_.
 Good practices
 --------------
 
-It is recommended setting access rights to file hierarchy leaves as much as
-possible.  For instance, it is better to be able to have ``~/doc/`` as a
-read-only hierarchy and ``~/tmp/`` as a read-write hierarchy, compared to
-``~/`` as a read-only hierarchy and ``~/tmp/`` as a read-write hierarchy.
-Following this good practice leads to self-sufficient hierarchies that do not
-depend on their location (i.e. parent directories).  This is particularly
-relevant when we want to allow linking or renaming.  Indeed, having consistent
-access rights per directory enables to change the location of such directory
-without relying on the destination directory access rights (except those that
-are required for this operation, see ``LANDLOCK_ACCESS_FS_REFER``
-documentation).
+It is recommended to set access rights to file hierarchy leaves as much as
+possible.  For instance, it is better to have a read-only ``~/doc/`` and
+read-write ``~/tmp/`` hierarchies, compared to read-only ``~/`` and
+read-write ``~/tmp/`` hierarchies. Following it leads to self-sufficient
+hierarchies that do not depend on their location (i.e. parent directories).
+This is particularly relevant when allowing linking or renaming is needed.
+Indeed, having consistent access rights per directory enables to change the
+location of such directory without relying on the destination directory access
+rights (except those that are required for this operation, see
+``LANDLOCK_ACCESS_FS_REFER`` documentation for example).
+
 Having self-sufficient hierarchies also helps to tighten the required access
 rights to the minimal set of data.  This also helps avoid sinkhole directories,
-i.e.  directories where data can be linked to but not linked from.  However,
-this depends on data organization, which might not be controlled by developers.
-In this case, granting read-write access to ``~/tmp/``, instead of write-only
-access, would potentially allow to move ``~/tmp/`` to a non-readable directory
-and still keep the ability to list the content of ``~/tmp/``.
+i.e.  directories where data can be linked to but not from.  However,
+this depends on data organization and layout, which may be outside developer
+control. In this case, granting read-write access instead of write-only to
+``~/tmp/`` would potentially allow to move ``~/tmp/`` to a non-readable
+directory and still keep the ability to list the content of ``~/tmp/``.
 
 Layers of file path access rights
 ---------------------------------
@@ -194,7 +195,7 @@ the potentially other rulesets already restricting this thread.  A sandboxed
 thread can then safely add more constraints to itself with a new enforced
 ruleset.
 
-One policy layer grants access to a file path if at least one of its rules
+A policy layer grants access to a file path if at least one of its rules
 encountered on the path grants the access.  A sandboxed thread can only access
 a file path if all its enforced policy layers grant the access as well as all
 the other system access controls (e.g. filesystem DAC, other LSM policies,
@@ -203,42 +204,40 @@ etc.).
 Bind mounts and OverlayFS
 -------------------------
 
-Landlock enables to restrict access to file hierarchies, which means that these
-access rights can be propagated with bind mounts (cf.
-Documentation/filesystems/sharedsubtree.rst) but not with
-Documentation/filesystems/overlayfs.rst.
+Landlock can restrict access to file hierarchies, which means that these
+access rights can be propagated with bind mounts (see
+:ref:`shared-subtrees`) but not with :ref:`OverlayFS <overlayfs>`.
 
 A bind mount mirrors a source file hierarchy to a destination.  The destination
 hierarchy is then composed of the exact same files, on which Landlock rules can
-be tied, either via the source or the destination path.  These rules restrict
-access when they are encountered on a path, which means that they can restrict
-access to multiple file hierarchies at the same time, whether these hierarchies
+be applied, either via the source or the destination path.  These rules
+restrict access when they are encountered on a path, which means that access
+to multiple file hierarchies can be restricted, whether these hierarchies
 are the result of bind mounts or not.
 
-An OverlayFS mount point consists of upper and lower layers.  These layers are
-combined in a merge directory, result of the mount point.  This merge hierarchy
-may include files from the upper and lower layers, but modifications performed
-on the merge hierarchy only reflects on the upper layer.  From a Landlock
-policy point of view, each OverlayFS layers and merge hierarchies are
-standalone and contains their own set of files and directories, which is
-different from bind mounts.  A policy restricting an OverlayFS layer will not
-restrict the resulted merged hierarchy, and vice versa.  Landlock users should
-then only think about file hierarchies they want to allow access to, regardless
-of the underlying filesystem.
+On the other hand, an OverlayFS mount point consists of upper and lower layers.
+These layers are combined in a merge directory; result of the mount point.
+This merge hierarchy may include files from the upper and lower layers, but
+modifications performed on the merge hierarchy only reflects on the upper
+layer. From a Landlock policy point of view, each OverlayFS layers and merge
+hierarchies are standalone and contains their own set of files and directories,
+which are different from bind mounts.  A policy restricting an OverlayFS layer
+will not restrict the resulted merged hierarchy, and vice versa. Landlock users
+should then only think about file hierarchies they want to allow access to,
+regardless of the underlying filesystem.
 
 Inheritance
 -----------
 
 Every new thread resulting from a :manpage:`clone(2)` inherits Landlock domain
-restrictions from its parent.  This is similar to the seccomp inheritance (cf.
-Documentation/userspace-api/seccomp_filter.rst) or any other LSM dealing with
-task's :manpage:`credentials(7)`.  For instance, one process's thread may apply
-Landlock rules to itself, but they will not be automatically applied to other
-sibling threads (unlike POSIX thread credential changes, cf.
-:manpage:`nptl(7)`).
+restrictions from its parent.  This is similar to the :ref:`seccomp-bpf`) or
+any other LSM dealing with task :manpage:`credentials(7)`. For instance, a
+process thread may apply Landlock rules to itself, but they will not be
+automatically applied to other sibling threads (unlike POSIX thread credential
+changes, see :manpage:`nptl(7)`).
 
-When a thread sandboxes itself, we have the guarantee that the related security
-policy will stay enforced on all this thread's descendants.  This allows
+When a thread sandboxes itself, there is a guarantee that the related security
+policy will stay enforced on all the thread descendants.  This allows
 creating standalone and modular security policies per application, which will
 automatically be composed between themselves according to their runtime parent
 policies.
@@ -259,18 +258,19 @@ Backward and forward compatibility
 ----------------------------------
 
 Landlock is designed to be compatible with past and future versions of the
-kernel.  This is achieved thanks to the system call attributes and the
-associated bitflags, particularly the ruleset's ``handled_access_fs``.  Making
-handled access right explicit enables the kernel and user space to have a clear
-contract with each other.  This is required to make sure sandboxing will not
-get stricter with a system update, which could break applications.
+kernel.  This is achieved bysystem call attributes and the associated bitflags,
+particularly the ``handled_access_fs`` of ruleset. Making access rights
+handling explicit enables the kernel and user space to have a clear contract
+with each other.  This is required to make sure sandboxing will not get
+stricter with a system update, which could break applications.
 
 Developers can subscribe to the `Landlock mailing list
-<https://subspace.kernel.org/lists.linux.dev.html>`_ to knowingly update and
-test their applications with the latest available features.  In the interest of
-users, and because they may use different kernel versions, it is strongly
-encouraged to follow a best-effort security approach by checking the Landlock
-ABI version at runtime and only enforcing the supported features.
+<https://subspace.kernel.org/lists.linux.dev.html>`_ to get to know with
+Landlock updates and test their applications with bleeding-edge features.
+In the interest of users, and because they may use different kernel versions,
+it is strongly encouraged to follow a best-effort security approach by
+checking the Landlock ABI version at runtime and only enforcing the supported
+features.
 
 .. _landlock_abi_versions:
 
@@ -345,7 +345,7 @@ Filesystem topology modification
 
 As for file renaming and linking, a sandboxed thread cannot modify its
 filesystem topology, whether via :manpage:`mount(2)` or
-:manpage:`pivot_root(2)`.  However, :manpage:`chroot(2)` calls are not denied.
+:manpage:`pivot_root(2)`.  However, :manpage:`chroot(2)` calls are allowed.
 
 Special filesystems
 -------------------
@@ -353,13 +353,11 @@ Special filesystems
 Access to regular files and directories can be restricted by Landlock,
 according to the handled accesses of a ruleset.  However, files that do not
 come from a user-visible filesystem (e.g. pipe, socket), but can still be
-accessed through ``/proc/<pid>/fd/*``, cannot currently be explicitly
-restricted.  Likewise, some special kernel filesystems such as nsfs, which can
-be accessed through ``/proc/<pid>/ns/*``, cannot currently be explicitly
-restricted.  However, thanks to the `ptrace restrictions`_, access to such
-sensitive ``/proc`` files are automatically restricted according to domain
-hierarchies.  Future Landlock evolutions could still enable to explicitly
-restrict such paths with dedicated ruleset flags.
+accessed through ``/proc/<pid>/fd/*``, cannot currently be restricted,
+and so some special kernel filesystems such as nsfs which can
+be accessed through ``/proc/<pid>/ns/*``. However, access to such
+sensitive ``/proc`` files are automatically restricted due to `ptrace restrictions`_ according to domain hierarchies. Future Landlock evolutions could still
+enable to explicitly restrict such paths with dedicated ruleset flags.
 
 Ruleset layers
 --------------
@@ -376,7 +374,7 @@ Memory usage
 ------------
 
 Kernel memory allocated to create rulesets is accounted and can be restricted
-by the Documentation/admin-guide/cgroup-v1/memory.rst.
+(see :ref:`cgroup-v1-memory`).
 
 Previous limitations
 ====================
@@ -386,7 +384,7 @@ File renaming and linking (ABI < 2)
 
 Because Landlock targets unprivileged access controls, it needs to properly
 handle composition of rules.  Such property also implies rules nesting.
-Properly handling multiple layers of rulesets, each one of them able to
+Properly handling multiple layers of rulesets, with each one of them able to
 restrict access to files, also implies inheritance of the ruleset restrictions
 from a parent to its hierarchy.  Because files are identified and restricted by
 their hierarchy, moving or linking a file from one directory to another implies
@@ -395,26 +393,24 @@ according to the potentially lost constraints.  To protect against privilege
 escalations through renaming or linking, and for the sake of simplicity,
 Landlock previously limited linking and renaming to the same directory.
 Starting with the Landlock ABI version 2, it is now possible to securely
-control renaming and linking thanks to the new ``LANDLOCK_ACCESS_FS_REFER``
-access right.
+control renaming and linking by ``LANDLOCK_ACCESS_FS_REFER``.
 
 .. _kernel_support:
 
 Kernel support
 ==============
 
-Landlock was first introduced in Linux 5.13 but it must be configured at build
-time with ``CONFIG_SECURITY_LANDLOCK=y``.  Landlock must also be enabled at boot
-time as the other security modules.  The list of security modules enabled by
-default is set with ``CONFIG_LSM``.  The kernel configuration should then
-contains ``CONFIG_LSM=landlock,[...]`` with ``[...]``  as the list of other
+Landlock was first introduced in Linux 5.13. To enable the support, the kernel
+must be configured at build time with ``CONFIG_SECURITY_LANDLOCK=y``. 
+Landlock must also be enabled at boot time like other security modules.
+The list of security modules enabled by default can be seen with
+``CONFIG_LSM``. The kernel configuration should then contains
+``CONFIG_LSM=landlock,[...]`` with ``[...]``  as the list of other
 potentially useful security modules for the running system (see the
 ``CONFIG_LSM`` help).
 
-If the running kernel does not have ``landlock`` in ``CONFIG_LSM``, then we can
-still enable it by adding ``lsm=landlock,[...]`` to
-Documentation/admin-guide/kernel-parameters.rst thanks to the bootloader
-configuration.
+If the running kernel does not have ``landlock`` in ``CONFIG_LSM``, then it can still be enabled by adding ``lsm=landlock,[...]`` kernel parameter (see
+:ref:`kernelparameters`)
 
 Questions and answers
 =====================
@@ -433,7 +429,7 @@ What about namespaces and containers?
 Namespaces can help create sandboxes but they are not designed for
 access-control and then miss useful features for such use case (e.g. no
 fine-grained restrictions).  Moreover, their complexity can lead to security
-issues, especially when untrusted processes can manipulate them (cf.
+issues, especially when untrusted processes can manipulate them (see
 `Controlling access to user namespaces <https://lwn.net/Articles/673597/>`_).
 
 Additional documentation
diff --git a/Documentation/userspace-api/seccomp_filter.rst b/Documentation/userspace-api/seccomp_filter.rst
index d1e2b9193f0984..a12782a958d43c 100644
--- a/Documentation/userspace-api/seccomp_filter.rst
+++ b/Documentation/userspace-api/seccomp_filter.rst
@@ -1,3 +1,5 @@
+.. _seccomp-bpf:
+
 ===========================================
 Seccomp BPF (SECure COMPuting with filters)
 ===========================================

Thanks.

-- 
An old man doll... just what I always wanted! - Clara

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply related	[relevance 5%]

* + mm-damon-dbgfs-implement-deprecation-notice-file-fix.patch added to mm-unstable branch
@ 2024-02-02 15:20  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2024-02-02 15:20 UTC (permalink / raw)
  To: mm-commits, sj, siyanteng, shuah, corbet, alexs, 2023002089, arnd,
	akpm


The patch titled
     Subject: mm/damon/dbgfs: fix bogus string length
has been added to the -mm mm-unstable branch.  Its filename is
     mm-damon-dbgfs-implement-deprecation-notice-file-fix.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-damon-dbgfs-implement-deprecation-notice-file-fix.patch

This patch will later appear in the mm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: Arnd Bergmann <arnd@arndb.de>
Subject: mm/damon/dbgfs: fix bogus string length
Date: Fri, 2 Feb 2024 13:43:26 +0100

gcc correctly points out that using strnlen() on a fixed size array
is nonsense with an overlong limit:

mm/damon/dbgfs.c: In function 'damon_dbgfs_deprecated_read':
mm/damon/dbgfs.c:814:19: error: 'strnlen' specified bound 1024 exceeds source size 512 [-Werror=stringop-overread]
  814 |         int len = strnlen(kbuf, 1024);
      |                   ^~~~~~~~~~~~~~~~~~~
mm/damon/dbgfs.c:813:14: note: source object allocated here
  813 |         char kbuf[512] = DAMON_DBGFS_DEPRECATION_NOTICE;
      |              ^~~~

In fact, neither of the arbitrary limits are needed here: The first
one can just be a static const string and avoid wasting any more
space then necessary, and the strnlen() can be either strlen() or
sizeof(kbuf)-1, both of which the compiler turns into the same
constant here.

Link: https://lkml.kernel.org/r/20240202124339.892862-1-arnd@kernel.org
Fixes: adf9047adfff ("mm/damon/dbgfs: implement deprecation notice file")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Alex Shi <alexs@kernel.org>
Cc: Hu Haowen <2023002089@link.tyut.edu.cn>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: SeongJae Park <sj@kernel.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Yanteng Si <siyanteng@loongson.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 mm/damon/dbgfs.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

--- a/mm/damon/dbgfs.c~mm-damon-dbgfs-implement-deprecation-notice-file-fix
+++ a/mm/damon/dbgfs.c
@@ -808,13 +808,12 @@ static void dbgfs_destroy_ctx(struct dam
 static ssize_t damon_dbgfs_deprecated_read(struct file *file,
 		char __user *buf, size_t count, loff_t *ppos)
 {
-	char kbuf[512] = "DAMON debugfs interface is deprecated, "
+	static const char kbuf[512] = "DAMON debugfs interface is deprecated, "
 		     "so users should move to DAMON_SYSFS. If you cannot, "
 		     "please report your usecase to damon@lists.linux.dev and "
 		     "linux-mm@kvack.org.\n";
-	int len = strnlen(kbuf, 1024);
 
-	return simple_read_from_buffer(buf, count, ppos, kbuf, len);
+	return simple_read_from_buffer(buf, count, ppos, kbuf, strlen(kbuf));
 }
 
 /*
_

Patches currently in -mm which might be from arnd@arndb.de are

mm-damon-dbgfs-implement-deprecation-notice-file-fix.patch


^ permalink raw reply	[relevance 5%]

* [PATCH RESEND 2 v7 1/5] dt-bindings: pwm: Add Apple PWM controller
    2023-02-14 15:57  5%   ` Sasha Finkelstein via B4 Submission Endpoint
@ 2023-02-14 15:57  5%   ` Sasha Finkelstein via B4 Submission Endpoint
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Submission Endpoint @ 2023-02-14 15:57 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH RESEND v9 1/5] dt-bindings: pwm: Add Apple PWM controller
    2023-04-03 14:19  5%   ` Sasha Finkelstein via B4 Relay
@ 2023-04-03 14:19  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Relay @ 2023-04-03 14:19 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-143)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v9 1/5] dt-bindings: pwm: Add Apple PWM controller
    2023-03-11  5:11  5%   ` Sasha Finkelstein via B4 Relay
@ 2023-03-11  5:11  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Relay @ 2023-03-11  5:11 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v8 1/5] dt-bindings: pwm: Add Apple PWM controller
    2023-03-10 18:44  5%   ` Sasha Finkelstein via B4 Relay
@ 2023-03-10 18:44  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Relay @ 2023-03-10 18:44 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v9 1/5] dt-bindings: pwm: Add Apple PWM controller
    2023-03-11  5:06  5%   ` Sasha Finkelstein via B4 Relay
@ 2023-03-11  5:06  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Relay @ 2023-03-11  5:06 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v3 2/2] dt-bindings: soc: add loongson-2 chipid
  2022-10-29  8:21  6% [PATCH v3 1/2] soc: loongson: add GUTS driver for loongson-2 platforms Yinbo Zhu
@ 2022-10-29  8:21  5% ` Yinbo Zhu
  0 siblings, 0 replies; 200+ results
From: Yinbo Zhu @ 2022-10-29  8:21 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, Yinbo Zhu

Add the Loongson-2 SoC chipid binding with DT schema format using
json-schema.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
---
Change in v3:
		1. Drop "driver" and describe instead what is GUTS, including
		   its acronym.
		2. Add desciption about the SoC register.
		3. Fixup dts node name.
		4. Replace string loongson2/Loongson2 with loongson-2/Loongson-2
                   in binding file and commit message.

 .../bindings/hwinfo/loongson,ls2k-chipid.yaml | 38 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 39 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml

diff --git a/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
new file mode 100644
index 000000000000..9d0c36ec1982
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwinfo/loongson,ls2k-chipid.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson-2 SoC ChipID
+
+maintainers:
+  - Yinbo Zhu <zhuyinbo@loongson.cn>
+
+description: |
+  Loongson-2 SoC contains many groups of global utilities register
+  blocks, of which the ChipID group registers record SoC version,
+  feature, vendor and id information.
+
+properties:
+  compatible:
+    const: loongson,ls2k-chipid
+
+  reg:
+    maxItems: 1
+
+  little-endian: true
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    chipid: chipid@1fe00000 {
+        compatible = "loongson,ls2k-chipid";
+        reg = <0x1fe00000 0x3ffc>;
+        little-endian;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index a02d45dd21ce..072da0f47f14 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11934,6 +11934,7 @@ LOONGSON-2 SOC SERIES GUTS DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	loongarch@lists.linux.dev
 S:	Maintained
+F:	Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
 F:	drivers/soc/loongson/loongson2_guts.c
 
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
-- 
2.31.1


^ permalink raw reply related	[relevance 5%]

* [PATCH RESEND 2 v7 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-02-14 15:57  5%   ` Sasha Finkelstein via B4 Submission Endpoint
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Submission Endpoint @ 2023-02-14 15:57 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH RESEND v9 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-04-03 14:19  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Relay @ 2023-04-03 14:19 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-143)


^ permalink raw reply related	[relevance 5%]

* [PATCH v9 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-03-11  5:11  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Relay @ 2023-03-11  5:11 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH v8 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-03-10 18:44  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Relay @ 2023-03-10 18:44 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH v9 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-03-11  5:06  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein via B4 Relay @ 2023-03-11  5:06 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

From: Sasha Finkelstein <fnkl.kernel@gmail.com>

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH v5 1/4] dt-bindings: pwm: Add Apple PWM controller
  @ 2022-12-21 21:06  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-12-21 21:06 UTC (permalink / raw)
  To: u.kleine-koenig, thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.1 (Apple Git-137.1)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v6 1/5] dt-bindings: pwm: Add Apple PWM controller
  @ 2023-01-06 13:58  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-01-06 13:58 UTC (permalink / raw)
  To: u.kleine-koenig, thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.1 (Apple Git-137.1)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v7 1/5] dt-bindings: pwm: Add Apple PWM controller
  @ 2023-01-14 13:25  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-01-14 13:25 UTC (permalink / raw)
  To: u.kleine-koenig, thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.1 (Apple Git-137.1)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v7 1/5] dt-bindings: pwm: Add Apple PWM controller
  @ 2023-01-25 15:10  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-01-25 15:10 UTC (permalink / raw)
  To: u.kleine-koenig, thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.1 (Apple Git-137.1)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v3] bus: mhi: host: Add soc_reset sysfs
@ 2022-04-18 17:18  5% Jeffrey Hugo
  0 siblings, 0 replies; 200+ results
From: Jeffrey Hugo @ 2022-04-18 17:18 UTC (permalink / raw)
  To: mani, quic_hemantk, quic_bbhatt
  Cc: mhi, linux-arm-msm, linux-kernel, Jeffrey Hugo

The MHI bus supports a standardized hardware reset, which is known as the
"SoC Reset".  This reset is similar to the reset sysfs for PCI devices -
a hardware mechanism to reset the state back to square one.

The MHI SoC Reset is described in the spec as a reset of last resort.  If
some unrecoverable error has occurred where other resets have failed, SoC
Reset is the "big hammer" that ungracefully resets the device.  This is
effectivly the same as yanking the power on the device, and reapplying it.
However, depending on the nature of the particular issue, the underlying
transport link may remain active and configured.  If the link remains up,
the device will flag a MHI system error early in the boot process after
the reset is executed, which allows the MHI bus to process a fatal error
event, and clean up appropiately.

While the SoC Reset is generally intended as a means of recovery when all
else has failed, it can be useful in non-error scenarios.  For example,
if the device loads firmware from the host filesystem, the device may need
to be fully rebooted inorder to pick up the new firmware.  In this
scenario, the system administrator may use the soc_reset sysfs to cause
the device to pick up the new firmware that the admin placed on the
filesystem.

Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
Reviewed-by: Bhaumik Bhatt <quic_bbhatt@quicinc.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---

v3:
Cleanup email domain change

v2:
Rebase

 Documentation/ABI/stable/sysfs-bus-mhi | 10 ++++++++++
 drivers/bus/mhi/host/init.c            | 14 ++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/Documentation/ABI/stable/sysfs-bus-mhi b/Documentation/ABI/stable/sysfs-bus-mhi
index ecfe766..96ccc33 100644
--- a/Documentation/ABI/stable/sysfs-bus-mhi
+++ b/Documentation/ABI/stable/sysfs-bus-mhi
@@ -19,3 +19,13 @@ Description:	The file holds the OEM PK Hash value of the endpoint device
 		read without having the device power on at least once, the file
 		will read all 0's.
 Users:		Any userspace application or clients interested in device info.
+
+What:           /sys/bus/mhi/devices/.../soc_reset
+Date:           April 2022
+KernelVersion:  5.19
+Contact:        mhi@lists.linux.dev
+Description:	Initiates a SoC reset on the MHI controller.  A SoC reset is
+                a reset of last resort, and will require a complete re-init.
+                This can be useful as a method of recovery if the device is
+                non-responsive, or as a means of loading new firmware as a
+                system administration task.
diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c
index a665b8e..a8c18c5f 100644
--- a/drivers/bus/mhi/host/init.c
+++ b/drivers/bus/mhi/host/init.c
@@ -108,9 +108,23 @@ static ssize_t oem_pk_hash_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(oem_pk_hash);
 
+static ssize_t soc_reset_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf,
+			       size_t count)
+{
+	struct mhi_device *mhi_dev = to_mhi_device(dev);
+	struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+
+	mhi_soc_reset(mhi_cntrl);
+	return count;
+}
+static DEVICE_ATTR_WO(soc_reset);
+
 static struct attribute *mhi_dev_attrs[] = {
 	&dev_attr_serial_number.attr,
 	&dev_attr_oem_pk_hash.attr,
+	&dev_attr_soc_reset.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(mhi_dev);
-- 
2.7.4


^ permalink raw reply related	[relevance 5%]

* [PATCH v2] bus: mhi: host: Add soc_reset sysfs
@ 2022-04-13 21:00  5% Jeffrey Hugo
  0 siblings, 0 replies; 200+ results
From: Jeffrey Hugo @ 2022-04-13 21:00 UTC (permalink / raw)
  To: mani, quic_hemantk, quic_bbhatt
  Cc: mhi, linux-arm-msm, linux-kernel, Jeffrey Hugo, Jeffrey Hugo

From: Jeffrey Hugo <jhugo@codeaurora.org>

The MHI bus supports a standardized hardware reset, which is known as the
"SoC Reset".  This reset is similar to the reset sysfs for PCI devices -
a hardware mechanism to reset the state back to square one.

The MHI SoC Reset is described in the spec as a reset of last resort.  If
some unrecoverable error has occurred where other resets have failed, SoC
Reset is the "big hammer" that ungracefully resets the device.  This is
effectivly the same as yanking the power on the device, and reapplying it.
However, depending on the nature of the particular issue, the underlying
transport link may remain active and configured.  If the link remains up,
the device will flag a MHI system error early in the boot process after
the reset is executed, which allows the MHI bus to process a fatal error
event, and clean up appropiately.

While the SoC Reset is generally intended as a means of recovery when all
else has failed, it can be useful in non-error scenarios.  For example,
if the device loads firmware from the host filesystem, the device may need
to be fully rebooted inorder to pick up the new firmware.  In this
scenario, the system administrator may use the soc_reset sysfs to cause
the device to pick up the new firmware that the admin placed on the
filesystem.

Signed-off-by: Jeffrey Hugo <jhugo@codeaurora.org>
Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
---

v2:
Rebase

 Documentation/ABI/stable/sysfs-bus-mhi | 11 +++++++++++
 drivers/bus/mhi/host/init.c            | 14 ++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/Documentation/ABI/stable/sysfs-bus-mhi b/Documentation/ABI/stable/sysfs-bus-mhi
index ecfe766..306f63e 100644
--- a/Documentation/ABI/stable/sysfs-bus-mhi
+++ b/Documentation/ABI/stable/sysfs-bus-mhi
@@ -19,3 +19,14 @@ Description:	The file holds the OEM PK Hash value of the endpoint device
 		read without having the device power on at least once, the file
 		will read all 0's.
 Users:		Any userspace application or clients interested in device info.
+
+What:           /sys/bus/mhi/devices/.../soc_reset
+Date:           April 2022
+KernelVersion:  5.19
+Contact:        mhi@lists.linux.dev
+Description:	Initiates a SoC reset on the MHI controller.  A SoC reset is
+                a reset of last resort, and will require a complete re-init.
+                This can be useful as a method of recovery if the device is
+                non-responsive, or as a means of loading new firmware as a
+                system administration task.
+
diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c
index 04c409b..e12b210 100644
--- a/drivers/bus/mhi/host/init.c
+++ b/drivers/bus/mhi/host/init.c
@@ -108,9 +108,23 @@ static ssize_t oem_pk_hash_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(oem_pk_hash);
 
+static ssize_t soc_reset_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf,
+			       size_t count)
+{
+	struct mhi_device *mhi_dev = to_mhi_device(dev);
+	struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+
+	mhi_soc_reset(mhi_cntrl);
+	return count;
+}
+static DEVICE_ATTR_WO(soc_reset);
+
 static struct attribute *mhi_dev_attrs[] = {
 	&dev_attr_serial_number.attr,
 	&dev_attr_oem_pk_hash.attr,
+	&dev_attr_soc_reset.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(mhi_dev);
-- 
2.7.4


^ permalink raw reply related	[relevance 5%]

* Re: [PATCH v5 0/2] soc: loongson2_pm: add power management support
  @ 2023-08-01  8:16  5%           ` Conor Dooley
  0 siblings, 0 replies; 200+ results
From: Conor Dooley @ 2023-08-01  8:16 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Huacai Chen, Conor.Dooley, Yinbo Zhu, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-pm, devicetree,
	linux-kernel, Jianmin Lv, wanghongliang, Liu Peibao,
	loongson-kernel, Liu Yun, WANG Xuerui

[-- Attachment #1: Type: text/plain, Size: 2411 bytes --]

On Mon, Jul 31, 2023 at 09:28:11PM +0200, Arnd Bergmann wrote:
> On Mon, Jul 31, 2023, at 16:13, Huacai Chen wrote:
> > On Fri, Jul 28, 2023 at 6:18 PM Conor Dooley <conor.dooley@microchip.com> wrote:
> 
> >>
> >> Perhaps that someone is you, or maybe it is Yinbo, up to you guys to
> >> decide :)
> > I'm a "merge hater" and "rebase lover", so I think it is better that
> > Arnd picks up these patches to the soc tree directly. But if
> > necessary, I can also create a "soc-loongson-next" branch in my tree
> > and then send PR to Arnd.
> 
> Separate patches are fine for a short series, it doesn't have
> to be a pull request, but do make sure to send it to
> soc@kernel.org after review is complete so I'll be sure to
> take care of it in patchwork, I otherwise skip a lot of
> patches as I expect them to be picked up into a platform
> specific tree first.
> 
> Also, if this ends up being a genpd driver, then patches
> after 6.6-rc1 need to go through Ulf's tree instead, not
> the soc tree.

Just to get the ball rolling, I've made the maintainers entry for you
Huacai :) Perhaps you can pick up the two patches I mentioned earlier in
the thread, as both appear to be fixes?

Thanks,
Conor.

-- >8 --
From 4423897634c0e54274df90a0a933e05f8f78074f Mon Sep 17 00:00:00 2001
From: Conor Dooley <conor.dooley@microchip.com>
Date: Tue, 1 Aug 2023 09:08:21 +0100
Subject: [PATCH] MAINTAINERS: add loongson soc driver entry

As a result of there being no entry covering Loongson SoC drivers, some
fixes have fallen through the cracks. Add Huacai Chen as a supporter of
drivers, who will forward patches to the SoC maintainers.

Link: https://lore.kernel.org/all/58500dc7-af1b-4edb-bb2b-93be454ec151@app.fastmail.com/
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3be1bdfe8ecc..0225bf871bab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12250,6 +12250,12 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml
 F:	drivers/i2c/busses/i2c-ls2x.c
 
+LOONGSON SOC DRIVERS
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	loongarch@lists.linux.dev
+S:	Supported
+F:	drivers/soc/loongson/
+
 LOONGSON-2 SOC SERIES CLOCK DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	linux-clk@vger.kernel.org
-- 
2.39.2



[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply related	[relevance 5%]

* [PATCH v2] MAINTAINERS: update Tzung-Bi's email address
@ 2022-10-25  2:49  5% Tzung-Bi Shih
  0 siblings, 0 replies; 200+ results
From: Tzung-Bi Shih @ 2022-10-25  2:49 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, tzungbi, wenst

Use kernel.org account instead.

Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
---
Changes from v1:
- Also update .mailmap.

 .mailmap                                                        | 1 +
 .../devicetree/bindings/sound/google,cros-ec-codec.yaml         | 2 +-
 Documentation/devicetree/bindings/sound/realtek,rt1015p.yaml    | 2 +-
 MAINTAINERS                                                     | 2 +-
 4 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/.mailmap b/.mailmap
index 380378e2db36..84342d781407 100644
--- a/.mailmap
+++ b/.mailmap
@@ -414,6 +414,7 @@ TripleX Chung <xxx.phy@gmail.com> <triplex@zh-kernel.org>
 TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn>
 Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com>
 Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws>
+Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com>
 Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
 Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
 Uwe Kleine-König <ukleinek@strlen.de>
diff --git a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
index c3e9f3485449..dea293f403d9 100644
--- a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
+++ b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
@@ -8,7 +8,7 @@ title: Audio codec controlled by ChromeOS EC
 
 maintainers:
   - Cheng-Yi Chiang <cychiang@chromium.org>
-  - Tzung-Bi Shih <tzungbi@google.com>
+  - Tzung-Bi Shih <tzungbi@kernel.org>
 
 description: |
   Google's ChromeOS EC codec is a digital mic codec provided by the
diff --git a/Documentation/devicetree/bindings/sound/realtek,rt1015p.yaml b/Documentation/devicetree/bindings/sound/realtek,rt1015p.yaml
index 1d73204451b1..ea7d4900ee4a 100644
--- a/Documentation/devicetree/bindings/sound/realtek,rt1015p.yaml
+++ b/Documentation/devicetree/bindings/sound/realtek,rt1015p.yaml
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Realtek rt1015p codec devicetree bindings
 
 maintainers:
-  - Tzung-Bi Shih <tzungbi@google.com>
+  - Tzung-Bi Shih <tzungbi@kernel.org>
 
 description: |
   Rt1015p is a rt1015 variant which does not support I2C and
diff --git a/MAINTAINERS b/MAINTAINERS
index cf0f18502372..f9749afc0b9d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4906,7 +4906,7 @@ F:	drivers/platform/chrome/
 
 CHROMEOS EC CODEC DRIVER
 M:	Cheng-Yi Chiang <cychiang@chromium.org>
-M:	Tzung-Bi Shih <tzungbi@google.com>
+M:	Tzung-Bi Shih <tzungbi@kernel.org>
 R:	Guenter Roeck <groeck@chromium.org>
 L:	chrome-platform@lists.linux.dev
 S:	Maintained
-- 
2.38.0.135.g90850a2211-goog


^ permalink raw reply related	[relevance 5%]

* [PATCH v4 1/4] dt-bindings: pwm: Add Apple PWM controller
  @ 2022-12-09 11:13  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-12-09 11:13 UTC (permalink / raw)
  To: thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.1 (Apple Git-137.1)


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH RESEND v3 1/4] dt-bindings: pwm: Add Apple PWM controller
  @ 2022-11-21 17:42  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-11-21 17:42 UTC (permalink / raw)
  To: thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.38.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v3 1/4] dt-bindings: pwm: Add Apple PWM controller
  @ 2022-11-11 17:33  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-11-11 17:33 UTC (permalink / raw)
  To: thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzyszstof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzyszstof Kozlowski <krzyszstof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.38.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v5 1/4] dt-bindings: pwm: Add Apple PWM controller
@ 2022-12-21 21:06  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-12-21 21:06 UTC (permalink / raw)
  To: u.kleine-koenig, thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.1 (Apple Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH v6 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-01-06 13:58  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-01-06 13:58 UTC (permalink / raw)
  To: u.kleine-koenig, thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.1 (Apple Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH v7 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-01-14 13:25  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-01-14 13:25 UTC (permalink / raw)
  To: u.kleine-koenig, thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.1 (Apple Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH v7 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-01-25 15:10  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-01-25 15:10 UTC (permalink / raw)
  To: u.kleine-koenig, thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.1 (Apple Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [merged mm-hotfixes-stable] maintainers-update-ocfs2-devel-mailing-list-address.patch removed from -mm tree
@ 2023-07-09  0:30  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2023-07-09  0:30 UTC (permalink / raw)
  To: mm-commits, piaojun, mark, junxiao.bi, jlbec, jiangqi903, ghe,
	gechangwei, ailiop, akpm


The quilt patch titled
     Subject: MAINTAINERS: update ocfs2-devel mailing list address
has been removed from the -mm tree.  Its filename was
     maintainers-update-ocfs2-devel-mailing-list-address.patch

This patch was dropped because it was merged into the mm-hotfixes-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

------------------------------------------------------
From: Anthony Iliopoulos <ailiop@suse.com>
Subject: MAINTAINERS: update ocfs2-devel mailing list address
Date: Wed, 28 Jun 2023 03:34:36 +0200

The ocfs2-devel mailing list has been migrated to the kernel.org
infrastructure, update the related entry to reflect the change.

Link: https://lkml.kernel.org/r/20230628013437.47030-2-ailiop@suse.com
Signed-off-by: Anthony Iliopoulos <ailiop@suse.com>
Acked-by: Joseph Qi <jiangqi903@gmail.com>
Acked-by: Joel Becker <jlbec@evilplan.org>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Gang He <ghe@suse.com>
Cc: Jun Piao <piaojun@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 MAINTAINERS |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/MAINTAINERS~maintainers-update-ocfs2-devel-mailing-list-address
+++ a/MAINTAINERS
@@ -15922,7 +15922,7 @@ ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
 M:	Mark Fasheh <mark@fasheh.com>
 M:	Joel Becker <jlbec@evilplan.org>
 M:	Joseph Qi <joseph.qi@linux.alibaba.com>
-L:	ocfs2-devel@oss.oracle.com (moderated for non-subscribers)
+L:	ocfs2-devel@lists.linux.dev
 S:	Supported
 W:	http://ocfs2.wiki.kernel.org
 F:	Documentation/filesystems/dlmfs.rst
_

Patches currently in -mm which might be from ailiop@suse.com are



^ permalink raw reply	[relevance 5%]

* [PATCH v4 1/4] dt-bindings: pwm: Add Apple PWM controller
@ 2022-12-09 11:13  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-12-09 11:13 UTC (permalink / raw)
  To: thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.1 (Apple Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH RESEND v3 1/4] dt-bindings: pwm: Add Apple PWM controller
@ 2022-11-21 17:42  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-11-21 17:42 UTC (permalink / raw)
  To: thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.38.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v13 1/2] spi: dt-bindings: add loongson spi
  @ 2023-06-13  7:58  5% ` Yinbo Zhu
  0 siblings, 0 replies; 200+ results
From: Yinbo Zhu @ 2023-06-13  7:58 UTC (permalink / raw)
  To: Mark Brown, Rob Herring, Krzysztof Kozlowski, linux-spi,
	devicetree, linux-kernel
  Cc: Jianmin Lv, wanghongliang, Liu Peibao, loongson-kernel, Yinbo Zhu,
	Krzysztof Kozlowski

Add the Loongson platform spi binding with DT schema format using
json-schema.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
 .../bindings/spi/loongson,ls2k-spi.yaml       | 46 +++++++++++++++++++
 MAINTAINERS                                   |  6 +++
 2 files changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml

diff --git a/Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml b/Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml
new file mode 100644
index 000000000000..de9d32feadf5
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/loongson,ls2k-spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson SPI controller
+
+maintainers:
+  - Yinbo Zhu <zhuyinbo@loongson.cn>
+
+allOf:
+  - $ref: /schemas/spi/spi-controller.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - loongson,ls2k1000-spi
+      - items:
+          - enum:
+              - loongson,ls2k0500-spi
+          - const: loongson,ls2k1000-spi
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    spi0: spi@1fff0220{
+        compatible = "loongson,ls2k1000-spi";
+        reg = <0x1fff0220 0x10>;
+        clocks = <&clk 17>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index bc201627c2e0..5e604dddd87b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12186,6 +12186,12 @@ F:	Documentation/devicetree/bindings/clock/loongson,ls2k-clk.yaml
 F:	drivers/clk/clk-loongson2.c
 F:	include/dt-bindings/clock/loongson,ls2k-clk.h
 
+LOONGSON SPI DRIVER
+M:	Yinbo Zhu <zhuyinbo@loongson.cn>
+L:	linux-spi@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml
+
 LOONGSON-2 SOC SERIES GUTS DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	loongarch@lists.linux.dev
-- 
2.20.1


^ permalink raw reply related	[relevance 5%]

* [PATCH RESEND 2 v7 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-02-14 15:57  5%   ` Sasha Finkelstein via B4 Submission Endpoint
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-02-14 15:57 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH v3 1/4] dt-bindings: pwm: Add Apple PWM controller
@ 2022-11-11 17:33  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-11-11 17:33 UTC (permalink / raw)
  To: thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein, Krzyszstof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzyszstof Kozlowski <krzyszstof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.38.1


^ permalink raw reply related	[relevance 5%]

* [PATCH RESEND v9 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-04-03 14:19  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-04-03 14:19 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-143)


^ permalink raw reply related	[relevance 5%]

* [PATCH v9 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-03-11  5:11  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-03-11  5:11 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH v8 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-03-10 18:44  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-03-10 18:44 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH v9 1/5] dt-bindings: pwm: Add Apple PWM controller
@ 2023-03-11  5:06  5%   ` Sasha Finkelstein via B4 Relay
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2023-03-11  5:06 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Rob Herring,
	Krzysztof Kozlowski, -, Sasha Finkelstein, Hector Martin,
	Sven Peter, Alyssa Rosenzweig
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	Krzysztof Kozlowski

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Sven Peter <sven@svenpeter.dev>
---
 .../devicetree/bindings/pwm/apple,s5l-fpwm.yaml    | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };

-- 
Git-137.1)


^ permalink raw reply related	[relevance 5%]

* [PATCH v3 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU
  @ 2024-04-30 20:01  5%   ` Tomasz Jeznach
  0 siblings, 0 replies; 200+ results
From: Tomasz Jeznach @ 2024-04-30 20:01 UTC (permalink / raw)
  To: Joerg Roedel, Will Deacon, Robin Murphy, Paul Walmsley
  Cc: Anup Patel, devicetree, Conor Dooley, Albert Ou, Tomasz Jeznach,
	linux, linux-kernel, Rob Herring, Sebastien Boeuf, iommu,
	Palmer Dabbelt, Nick Kossifidis, Krzysztof Kozlowski, linux-riscv

Add bindings for the RISC-V IOMMU device drivers.

Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com>
---
 .../bindings/iommu/riscv,iommu.yaml           | 150 ++++++++++++++++++
 MAINTAINERS                                   |   7 +
 2 files changed, 157 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/riscv,iommu.yaml

diff --git a/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
new file mode 100644
index 000000000000..16817525e157
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
@@ -0,0 +1,150 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/riscv,iommu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V IOMMU Architecture Implementation
+
+maintainers:
+  - Tomasz Jeznach <tjeznach@rivosinc.com>
+
+description: |
+  The RISC-V IOMMU provides memory address translation and isolation for
+  input and output devices, supporting per-device translation context,
+  shared process address spaces including the ATS and PRI components of
+  the PCIe specification, two stage address translation and MSI remapping.
+  It supports identical translation table format to the RISC-V address
+  translation tables with page level access and protection attributes.
+  Hardware uses in-memory command and fault reporting queues with wired
+  interrupt or MSI notifications.
+
+  Visit https://github.com/riscv-non-isa/riscv-iommu for more details.
+
+  For information on assigning RISC-V IOMMU to its peripheral devices,
+  see generic IOMMU bindings.
+
+properties:
+  # For PCIe IOMMU hardware compatible property should contain the vendor
+  # and device ID according to the PCI Bus Binding specification.
+  # Since PCI provides built-in identification methods, compatible is not
+  # actually required. For non-PCIe hardware implementations 'riscv,iommu'
+  # should be specified along with 'reg' property providing MMIO location.
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - qemu,iommu
+          - const: riscv,iommu
+      - items:
+          - enum:
+              - pci1efd,edf1
+          - const: riscv,pci-iommu
+
+  reg:
+    maxItems: 1
+    description:
+      For non-PCI devices this represents base address and size of for the
+      IOMMU memory mapped registers interface.
+      For PCI IOMMU hardware implementation this should represent an address
+      of the IOMMU, as defined in the PCI Bus Binding reference. The reg
+      property is a five-cell address encoded as (phys.hi phys.mid phys.lo
+      size.hi size.lo), where phys.hi should contain the device's BDF as
+      0b00000000 bbbbbbbb dddddfff 00000000. The other cells should be zero.
+
+  '#iommu-cells':
+    const: 1
+    description:
+      Has to be one. The single cell describes the requester id emitted
+      by a master to the IOMMU.
+
+  interrupts:
+    minItems: 1
+    maxItems: 4
+    description:
+      Wired interrupt vectors available for RISC-V IOMMU to notify the
+      RISC-V HARTS. The cause to interrupt vector is software defined
+      using IVEC IOMMU register.
+
+  msi-parent: true
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - '#iommu-cells'
+
+additionalProperties: false
+
+examples:
+  - |+
+    /* Example 1 (IOMMU device with wired interrupts) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu1: iommu@1bccd000 {
+        compatible = "qemu,iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
+                     <33 IRQ_TYPE_LEVEL_HIGH>,
+                     <34 IRQ_TYPE_LEVEL_HIGH>,
+                     <35 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+    /* Device with two IOMMU device IDs, 0 and 7 */
+    master1 {
+        iommus = <&iommu1 0>, <&iommu1 7>;
+    };
+
+  - |+
+    /* Example 2 (IOMMU device with shared wired interrupt) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu2: iommu@1bccd000 {
+        compatible = "qemu,iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 3 (IOMMU device with MSIs) */
+    iommu3: iommu@1bcdd000 {
+        compatible = "qemu,iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        msi-parent = <&imsics_smode>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 4 (IOMMU PCIe device with MSIs) */
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pcie@30000000 {
+            device_type = "pci";
+            #address-cells = <3>;
+            #size-cells = <2>;
+            reg = <0x0 0x30000000  0x0 0x1000000>;
+            ranges = <0x02000000 0x0 0x41000000  0x0 0x41000000  0x0 0x0f000000>;
+
+            /*
+             * The IOMMU manages all functions in this PCI domain except
+             * itself. Omit BDF 00:01.0.
+             */
+            iommu-map = <0x0 &iommu0 0x0 0x8
+                         0x9 &iommu0 0x9 0xfff7>;
+
+            /* The IOMMU programming interface uses slot 00:01.0 */
+            iommu0: iommu@1,0 {
+               compatible = "pci1efd,edf1", "riscv,pci-iommu";
+               reg = <0x800 0 0 0 0>;
+               #iommu-cells = <1>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index f6dc90559341..7fcf7c27ef6b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18958,6 +18958,13 @@ F:	arch/riscv/
 N:	riscv
 K:	riscv
 
+RISC-V IOMMU
+M:	Tomasz Jeznach <tjeznach@rivosinc.com>
+L:	iommu@lists.linux.dev
+L:	linux-riscv@lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
+
 RISC-V MICROCHIP FPGA SUPPORT
 M:	Conor Dooley <conor.dooley@microchip.com>
 M:	Daire McNamara <daire.mcnamara@microchip.com>
-- 
2.34.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[relevance 5%]

* [PATCH v3 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU
@ 2024-04-30 20:01  5%   ` Tomasz Jeznach
  0 siblings, 0 replies; 200+ results
From: Tomasz Jeznach @ 2024-04-30 20:01 UTC (permalink / raw)
  To: Joerg Roedel, Will Deacon, Robin Murphy, Paul Walmsley
  Cc: Palmer Dabbelt, Albert Ou, Anup Patel, Sunil V L, Nick Kossifidis,
	Sebastien Boeuf, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	devicetree, iommu, linux-riscv, linux-kernel, linux,
	Tomasz Jeznach

Add bindings for the RISC-V IOMMU device drivers.

Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com>
---
 .../bindings/iommu/riscv,iommu.yaml           | 150 ++++++++++++++++++
 MAINTAINERS                                   |   7 +
 2 files changed, 157 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/riscv,iommu.yaml

diff --git a/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
new file mode 100644
index 000000000000..16817525e157
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
@@ -0,0 +1,150 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/riscv,iommu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V IOMMU Architecture Implementation
+
+maintainers:
+  - Tomasz Jeznach <tjeznach@rivosinc.com>
+
+description: |
+  The RISC-V IOMMU provides memory address translation and isolation for
+  input and output devices, supporting per-device translation context,
+  shared process address spaces including the ATS and PRI components of
+  the PCIe specification, two stage address translation and MSI remapping.
+  It supports identical translation table format to the RISC-V address
+  translation tables with page level access and protection attributes.
+  Hardware uses in-memory command and fault reporting queues with wired
+  interrupt or MSI notifications.
+
+  Visit https://github.com/riscv-non-isa/riscv-iommu for more details.
+
+  For information on assigning RISC-V IOMMU to its peripheral devices,
+  see generic IOMMU bindings.
+
+properties:
+  # For PCIe IOMMU hardware compatible property should contain the vendor
+  # and device ID according to the PCI Bus Binding specification.
+  # Since PCI provides built-in identification methods, compatible is not
+  # actually required. For non-PCIe hardware implementations 'riscv,iommu'
+  # should be specified along with 'reg' property providing MMIO location.
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - qemu,iommu
+          - const: riscv,iommu
+      - items:
+          - enum:
+              - pci1efd,edf1
+          - const: riscv,pci-iommu
+
+  reg:
+    maxItems: 1
+    description:
+      For non-PCI devices this represents base address and size of for the
+      IOMMU memory mapped registers interface.
+      For PCI IOMMU hardware implementation this should represent an address
+      of the IOMMU, as defined in the PCI Bus Binding reference. The reg
+      property is a five-cell address encoded as (phys.hi phys.mid phys.lo
+      size.hi size.lo), where phys.hi should contain the device's BDF as
+      0b00000000 bbbbbbbb dddddfff 00000000. The other cells should be zero.
+
+  '#iommu-cells':
+    const: 1
+    description:
+      Has to be one. The single cell describes the requester id emitted
+      by a master to the IOMMU.
+
+  interrupts:
+    minItems: 1
+    maxItems: 4
+    description:
+      Wired interrupt vectors available for RISC-V IOMMU to notify the
+      RISC-V HARTS. The cause to interrupt vector is software defined
+      using IVEC IOMMU register.
+
+  msi-parent: true
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - '#iommu-cells'
+
+additionalProperties: false
+
+examples:
+  - |+
+    /* Example 1 (IOMMU device with wired interrupts) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu1: iommu@1bccd000 {
+        compatible = "qemu,iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
+                     <33 IRQ_TYPE_LEVEL_HIGH>,
+                     <34 IRQ_TYPE_LEVEL_HIGH>,
+                     <35 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+    /* Device with two IOMMU device IDs, 0 and 7 */
+    master1 {
+        iommus = <&iommu1 0>, <&iommu1 7>;
+    };
+
+  - |+
+    /* Example 2 (IOMMU device with shared wired interrupt) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu2: iommu@1bccd000 {
+        compatible = "qemu,iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 3 (IOMMU device with MSIs) */
+    iommu3: iommu@1bcdd000 {
+        compatible = "qemu,iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        msi-parent = <&imsics_smode>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 4 (IOMMU PCIe device with MSIs) */
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pcie@30000000 {
+            device_type = "pci";
+            #address-cells = <3>;
+            #size-cells = <2>;
+            reg = <0x0 0x30000000  0x0 0x1000000>;
+            ranges = <0x02000000 0x0 0x41000000  0x0 0x41000000  0x0 0x0f000000>;
+
+            /*
+             * The IOMMU manages all functions in this PCI domain except
+             * itself. Omit BDF 00:01.0.
+             */
+            iommu-map = <0x0 &iommu0 0x0 0x8
+                         0x9 &iommu0 0x9 0xfff7>;
+
+            /* The IOMMU programming interface uses slot 00:01.0 */
+            iommu0: iommu@1,0 {
+               compatible = "pci1efd,edf1", "riscv,pci-iommu";
+               reg = <0x800 0 0 0 0>;
+               #iommu-cells = <1>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index f6dc90559341..7fcf7c27ef6b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18958,6 +18958,13 @@ F:	arch/riscv/
 N:	riscv
 K:	riscv
 
+RISC-V IOMMU
+M:	Tomasz Jeznach <tjeznach@rivosinc.com>
+L:	iommu@lists.linux.dev
+L:	linux-riscv@lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
+
 RISC-V MICROCHIP FPGA SUPPORT
 M:	Conor Dooley <conor.dooley@microchip.com>
 M:	Daire McNamara <daire.mcnamara@microchip.com>
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v5 1/3] bus: mhi: host: Add sysfs entry to force device to enter EDL
  @ 2024-04-24  3:21  5% ` Qiang Yu
  0 siblings, 0 replies; 200+ results
From: Qiang Yu @ 2024-04-24  3:21 UTC (permalink / raw)
  To: mani, quic_jhugo
  Cc: mhi, linux-arm-msm, linux-kernel, quic_cang, quic_mrana, Qiang Yu

Add sysfs entry to allow users of MHI bus force device to enter EDL.
Considering that the way to enter EDL mode varies from device to device and
some devices even do not support EDL. Hence, add a callback edl_trigger in
mhi controller as part of the sysfs entry to be invoked and MHI core will
only create EDL sysfs entry for mhi controller that provides edl_trigger
callback. All of the process a specific device required to enter EDL mode
can be placed in this callback.

Signed-off-by: Qiang Yu <quic_qianyu@quicinc.com>
Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
---
 Documentation/ABI/stable/sysfs-bus-mhi | 13 +++++++++++++
 drivers/bus/mhi/host/init.c            | 33 +++++++++++++++++++++++++++++++++
 include/linux/mhi.h                    |  2 ++
 3 files changed, 48 insertions(+)

diff --git a/Documentation/ABI/stable/sysfs-bus-mhi b/Documentation/ABI/stable/sysfs-bus-mhi
index 1a47f9e..b44f467 100644
--- a/Documentation/ABI/stable/sysfs-bus-mhi
+++ b/Documentation/ABI/stable/sysfs-bus-mhi
@@ -29,3 +29,16 @@ Description:	Initiates a SoC reset on the MHI controller.  A SoC reset is
                 This can be useful as a method of recovery if the device is
                 non-responsive, or as a means of loading new firmware as a
                 system administration task.
+
+What:           /sys/bus/mhi/devices/.../trigger_edl
+Date:           April 2024
+KernelVersion:  6.9
+Contact:        mhi@lists.linux.dev
+Description:    Writing a non-zero value to this file will force devices to
+                enter EDL (Emergency Download) mode. This entry only exists for
+                devices capable of entering the EDL mode using the standard EDL
+                triggering mechanism defined in the MHI spec v1.2. Once in EDL
+                mode, the flash programmer image can be downloaded to the
+                device to enter the flash programmer execution environment.
+                This can be useful if user wants to use QDL (Qualcomm Download,
+                which is used to download firmware over EDL) to update firmware.
diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c
index 44f9349..7104c18 100644
--- a/drivers/bus/mhi/host/init.c
+++ b/drivers/bus/mhi/host/init.c
@@ -127,6 +127,30 @@ static ssize_t soc_reset_store(struct device *dev,
 }
 static DEVICE_ATTR_WO(soc_reset);
 
+static ssize_t trigger_edl_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct mhi_device *mhi_dev = to_mhi_device(dev);
+	struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+	unsigned long val;
+	int ret;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret < 0)
+		return ret;
+
+	if (!val)
+		return -EINVAL;
+
+	ret = mhi_cntrl->edl_trigger(mhi_cntrl);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static DEVICE_ATTR_WO(trigger_edl);
+
 static struct attribute *mhi_dev_attrs[] = {
 	&dev_attr_serial_number.attr,
 	&dev_attr_oem_pk_hash.attr,
@@ -1018,6 +1042,12 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
 	if (ret)
 		goto err_release_dev;
 
+	if (mhi_cntrl->edl_trigger) {
+		ret = sysfs_create_file(&mhi_dev->dev.kobj, &dev_attr_trigger_edl.attr);
+		if (ret)
+			goto err_release_dev;
+	}
+
 	mhi_cntrl->mhi_dev = mhi_dev;
 
 	mhi_create_debugfs(mhi_cntrl);
@@ -1051,6 +1081,9 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl)
 	mhi_deinit_free_irq(mhi_cntrl);
 	mhi_destroy_debugfs(mhi_cntrl);
 
+	if (mhi_cntrl->edl_trigger)
+		sysfs_remove_file(&mhi_dev->dev.kobj, &dev_attr_trigger_edl.attr);
+
 	destroy_workqueue(mhi_cntrl->hiprio_wq);
 	kfree(mhi_cntrl->mhi_cmd);
 	kfree(mhi_cntrl->mhi_event);
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index cde01e1..d968e1a 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -353,6 +353,7 @@ struct mhi_controller_config {
  * @read_reg: Read a MHI register via the physical link (required)
  * @write_reg: Write a MHI register via the physical link (required)
  * @reset: Controller specific reset function (optional)
+ * @edl_trigger: CB function to trigger EDL mode (optional)
  * @buffer_len: Bounce buffer length
  * @index: Index of the MHI controller instance
  * @bounce_buf: Use of bounce buffer
@@ -435,6 +436,7 @@ struct mhi_controller {
 	void (*write_reg)(struct mhi_controller *mhi_cntrl, void __iomem *addr,
 			  u32 val);
 	void (*reset)(struct mhi_controller *mhi_cntrl);
+	int (*edl_trigger)(struct mhi_controller *mhi_cntrl);
 
 	size_t buffer_len;
 	int index;
-- 
2.7.4


^ permalink raw reply related	[relevance 5%]

* [PATCH v2 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU
  @ 2024-04-18 16:32  5%   ` Tomasz Jeznach
  0 siblings, 0 replies; 200+ results
From: Tomasz Jeznach @ 2024-04-18 16:32 UTC (permalink / raw)
  To: Joerg Roedel, Will Deacon, Robin Murphy, Paul Walmsley
  Cc: Anup Patel, devicetree, Conor Dooley, Albert Ou, Tomasz Jeznach,
	linux, linux-kernel, Rob Herring, Sebastien Boeuf, iommu,
	Palmer Dabbelt, Nick Kossifidis, Krzysztof Kozlowski, linux-riscv

Add bindings for the RISC-V IOMMU device drivers.

Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com>
---
 .../bindings/iommu/riscv,iommu.yaml           | 149 ++++++++++++++++++
 MAINTAINERS                                   |   7 +
 2 files changed, 156 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/riscv,iommu.yaml

diff --git a/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
new file mode 100644
index 000000000000..d6522ddd43fa
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
@@ -0,0 +1,149 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/riscv,iommu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V IOMMU Architecture Implementation
+
+maintainers:
+  - Tomasz Jeznach <tjeznach@rivosinc.com>
+
+description: |+
+  The RISC-V IOMMU provides memory address translation and isolation for
+  input and output devices, supporting per-device translation context,
+  shared process address spaces including the ATS and PRI components of
+  the PCIe specification, two stage address translation and MSI remapping.
+  It supports identical translation table format to the RISC-V address
+  translation tables with page level access and protection attributes.
+  Hardware uses in-memory command and fault reporting queues with wired
+  interrupt or MSI notifications.
+
+  Visit https://github.com/riscv-non-isa/riscv-iommu for more details.
+
+  For information on assigning RISC-V IOMMU to its peripheral devices,
+  see generic IOMMU bindings.
+
+properties:
+  # For PCIe IOMMU hardware compatible property should contain the vendor
+  # and device ID according to the PCI Bus Binding specification.
+  # Since PCI provides built-in identification methods, compatible is not
+  # actually required. For non-PCIe hardware implementations 'riscv,iommu'
+  # should be specified along with 'reg' property providing MMIO location.
+  compatible:
+    oneOf:
+      - items:
+          - const: riscv,pci-iommu
+          - const: pci1efd,edf1
+      - items:
+          - const: pci1efd,edf1
+      - items:
+          - const: riscv,iommu
+
+  reg:
+    maxItems: 1
+    description:
+      For non-PCI devices this represents base address and size of for the
+      IOMMU memory mapped registers interface.
+      For PCI IOMMU hardware implementation this should represent an address
+      of the IOMMU, as defined in the PCI Bus Binding reference. The reg
+      property is a five-cell address encoded as (phys.hi phys.mid phys.lo
+      size.hi size.lo), where phys.hi should contain the device's BDF as
+      0b00000000 bbbbbbbb dddddfff 00000000. The other cells should be zero.
+
+  '#iommu-cells':
+    const: 1
+    description:
+      Has to be one. The single cell describes the requester id emitted
+      by a master to the IOMMU.
+
+  interrupts:
+    minItems: 1
+    maxItems: 4
+    description:
+      Wired interrupt vectors available for RISC-V IOMMU to notify the
+      RISC-V HARTS. The cause to interrupt vector is software defined
+      using IVEC IOMMU register.
+
+  msi-parent: true
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - '#iommu-cells'
+
+additionalProperties: false
+
+examples:
+  - |+
+    /* Example 1 (IOMMU device with wired interrupts) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu1: iommu@1bccd000 {
+        compatible = "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
+                     <33 IRQ_TYPE_LEVEL_HIGH>,
+                     <34 IRQ_TYPE_LEVEL_HIGH>,
+                     <35 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+    /* Device with two IOMMU device IDs, 0 and 7 */
+    master1 {
+        iommus = <&iommu1 0>, <&iommu1 7>;
+    };
+
+  - |+
+    /* Example 2 (IOMMU device with shared wired interrupt) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu2: iommu@1bccd000 {
+        compatible = "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 3 (IOMMU device with MSIs) */
+    iommu3: iommu@1bcdd000 {
+        compatible = "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        msi-parent = <&imsics_smode>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 4 (IOMMU PCIe device with MSIs) */
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pcie@30000000 {
+            device_type = "pci";
+            #address-cells = <3>;
+            #size-cells = <2>;
+            reg = <0x0 0x30000000  0x0 0x1000000>;
+            ranges = <0x02000000 0x0 0x41000000  0x0 0x41000000  0x0 0x0f000000>;
+
+            /*
+             * The IOMMU manages all functions in this PCI domain except
+             * itself. Omit BDF 00:01.0.
+             */
+            iommu-map = <0x0 &iommu0 0x0 0x8
+                         0x9 &iommu0 0x9 0xfff7>;
+
+            /* The IOMMU programming interface uses slot 00:01.0 */
+            iommu0: iommu@1,0 {
+               compatible = "pci1efd,edf1";
+               reg = <0x800 0 0 0 0>;
+               #iommu-cells = <1>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index c23fda1aa1f0..2657f9eae84c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18966,6 +18966,13 @@ F:	arch/riscv/
 N:	riscv
 K:	riscv
 
+RISC-V IOMMU
+M:	Tomasz Jeznach <tjeznach@rivosinc.com>
+L:	iommu@lists.linux.dev
+L:	linux-riscv@lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
+
 RISC-V MICROCHIP FPGA SUPPORT
 M:	Conor Dooley <conor.dooley@microchip.com>
 M:	Daire McNamara <daire.mcnamara@microchip.com>
-- 
2.34.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[relevance 5%]

* [PATCH v2 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU
@ 2024-04-18 16:32  5%   ` Tomasz Jeznach
  0 siblings, 0 replies; 200+ results
From: Tomasz Jeznach @ 2024-04-18 16:32 UTC (permalink / raw)
  To: Joerg Roedel, Will Deacon, Robin Murphy, Paul Walmsley
  Cc: Palmer Dabbelt, Albert Ou, Anup Patel, Sunil V L, Nick Kossifidis,
	Sebastien Boeuf, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	devicetree, iommu, linux-riscv, linux-kernel, linux,
	Tomasz Jeznach

Add bindings for the RISC-V IOMMU device drivers.

Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com>
---
 .../bindings/iommu/riscv,iommu.yaml           | 149 ++++++++++++++++++
 MAINTAINERS                                   |   7 +
 2 files changed, 156 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/riscv,iommu.yaml

diff --git a/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
new file mode 100644
index 000000000000..d6522ddd43fa
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
@@ -0,0 +1,149 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/riscv,iommu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V IOMMU Architecture Implementation
+
+maintainers:
+  - Tomasz Jeznach <tjeznach@rivosinc.com>
+
+description: |+
+  The RISC-V IOMMU provides memory address translation and isolation for
+  input and output devices, supporting per-device translation context,
+  shared process address spaces including the ATS and PRI components of
+  the PCIe specification, two stage address translation and MSI remapping.
+  It supports identical translation table format to the RISC-V address
+  translation tables with page level access and protection attributes.
+  Hardware uses in-memory command and fault reporting queues with wired
+  interrupt or MSI notifications.
+
+  Visit https://github.com/riscv-non-isa/riscv-iommu for more details.
+
+  For information on assigning RISC-V IOMMU to its peripheral devices,
+  see generic IOMMU bindings.
+
+properties:
+  # For PCIe IOMMU hardware compatible property should contain the vendor
+  # and device ID according to the PCI Bus Binding specification.
+  # Since PCI provides built-in identification methods, compatible is not
+  # actually required. For non-PCIe hardware implementations 'riscv,iommu'
+  # should be specified along with 'reg' property providing MMIO location.
+  compatible:
+    oneOf:
+      - items:
+          - const: riscv,pci-iommu
+          - const: pci1efd,edf1
+      - items:
+          - const: pci1efd,edf1
+      - items:
+          - const: riscv,iommu
+
+  reg:
+    maxItems: 1
+    description:
+      For non-PCI devices this represents base address and size of for the
+      IOMMU memory mapped registers interface.
+      For PCI IOMMU hardware implementation this should represent an address
+      of the IOMMU, as defined in the PCI Bus Binding reference. The reg
+      property is a five-cell address encoded as (phys.hi phys.mid phys.lo
+      size.hi size.lo), where phys.hi should contain the device's BDF as
+      0b00000000 bbbbbbbb dddddfff 00000000. The other cells should be zero.
+
+  '#iommu-cells':
+    const: 1
+    description:
+      Has to be one. The single cell describes the requester id emitted
+      by a master to the IOMMU.
+
+  interrupts:
+    minItems: 1
+    maxItems: 4
+    description:
+      Wired interrupt vectors available for RISC-V IOMMU to notify the
+      RISC-V HARTS. The cause to interrupt vector is software defined
+      using IVEC IOMMU register.
+
+  msi-parent: true
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - '#iommu-cells'
+
+additionalProperties: false
+
+examples:
+  - |+
+    /* Example 1 (IOMMU device with wired interrupts) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu1: iommu@1bccd000 {
+        compatible = "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
+                     <33 IRQ_TYPE_LEVEL_HIGH>,
+                     <34 IRQ_TYPE_LEVEL_HIGH>,
+                     <35 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+    /* Device with two IOMMU device IDs, 0 and 7 */
+    master1 {
+        iommus = <&iommu1 0>, <&iommu1 7>;
+    };
+
+  - |+
+    /* Example 2 (IOMMU device with shared wired interrupt) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu2: iommu@1bccd000 {
+        compatible = "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 3 (IOMMU device with MSIs) */
+    iommu3: iommu@1bcdd000 {
+        compatible = "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        msi-parent = <&imsics_smode>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 4 (IOMMU PCIe device with MSIs) */
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pcie@30000000 {
+            device_type = "pci";
+            #address-cells = <3>;
+            #size-cells = <2>;
+            reg = <0x0 0x30000000  0x0 0x1000000>;
+            ranges = <0x02000000 0x0 0x41000000  0x0 0x41000000  0x0 0x0f000000>;
+
+            /*
+             * The IOMMU manages all functions in this PCI domain except
+             * itself. Omit BDF 00:01.0.
+             */
+            iommu-map = <0x0 &iommu0 0x0 0x8
+                         0x9 &iommu0 0x9 0xfff7>;
+
+            /* The IOMMU programming interface uses slot 00:01.0 */
+            iommu0: iommu@1,0 {
+               compatible = "pci1efd,edf1";
+               reg = <0x800 0 0 0 0>;
+               #iommu-cells = <1>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index c23fda1aa1f0..2657f9eae84c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18966,6 +18966,13 @@ F:	arch/riscv/
 N:	riscv
 K:	riscv
 
+RISC-V IOMMU
+M:	Tomasz Jeznach <tjeznach@rivosinc.com>
+L:	iommu@lists.linux.dev
+L:	linux-riscv@lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
+
 RISC-V MICROCHIP FPGA SUPPORT
 M:	Conor Dooley <conor.dooley@microchip.com>
 M:	Daire McNamara <daire.mcnamara@microchip.com>
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v5 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU
  @ 2024-05-14 18:16  5%   ` Tomasz Jeznach
  0 siblings, 0 replies; 200+ results
From: Tomasz Jeznach @ 2024-05-14 18:16 UTC (permalink / raw)
  To: Joerg Roedel, Will Deacon, Robin Murphy, Paul Walmsley
  Cc: Anup Patel, devicetree, Conor Dooley, Albert Ou, Tomasz Jeznach,
	linux, Rob Herring, Conor Dooley, linux-kernel, Rob Herring,
	Sebastien Boeuf, iommu, Palmer Dabbelt, Nick Kossifidis,
	Krzysztof Kozlowski, linux-riscv

Add bindings for the RISC-V IOMMU device drivers.

Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com>
---
 .../bindings/iommu/riscv,iommu.yaml           | 147 ++++++++++++++++++
 MAINTAINERS                                   |   7 +
 2 files changed, 154 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/riscv,iommu.yaml

diff --git a/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
new file mode 100644
index 000000000000..5d015eeb06d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/riscv,iommu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V IOMMU Architecture Implementation
+
+maintainers:
+  - Tomasz Jeznach <tjeznach@rivosinc.com>
+
+description: |
+  The RISC-V IOMMU provides memory address translation and isolation for
+  input and output devices, supporting per-device translation context,
+  shared process address spaces including the ATS and PRI components of
+  the PCIe specification, two stage address translation and MSI remapping.
+  It supports identical translation table format to the RISC-V address
+  translation tables with page level access and protection attributes.
+  Hardware uses in-memory command and fault reporting queues with wired
+  interrupt or MSI notifications.
+
+  Visit https://github.com/riscv-non-isa/riscv-iommu for more details.
+
+  For information on assigning RISC-V IOMMU to its peripheral devices,
+  see generic IOMMU bindings.
+
+properties:
+  # For PCIe IOMMU hardware compatible property should contain the vendor
+  # and device ID according to the PCI Bus Binding specification.
+  # Since PCI provides built-in identification methods, compatible is not
+  # actually required. For non-PCIe hardware implementations 'riscv,iommu'
+  # should be specified along with 'reg' property providing MMIO location.
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - qemu,riscv-iommu
+          - const: riscv,iommu
+      - items:
+          - enum:
+              - pci1efd,edf1
+          - const: riscv,pci-iommu
+
+  reg:
+    maxItems: 1
+    description:
+      For non-PCI devices this represents base address and size of for the
+      IOMMU memory mapped registers interface.
+      For PCI IOMMU hardware implementation this should represent an address
+      of the IOMMU, as defined in the PCI Bus Binding reference.
+
+  '#iommu-cells':
+    const: 1
+    description:
+      The single cell describes the requester id emitted by a master to the
+      IOMMU.
+
+  interrupts:
+    minItems: 1
+    maxItems: 4
+    description:
+      Wired interrupt vectors available for RISC-V IOMMU to notify the
+      RISC-V HARTS. The cause to interrupt vector is software defined
+      using IVEC IOMMU register.
+
+  msi-parent: true
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - '#iommu-cells'
+
+additionalProperties: false
+
+examples:
+  - |+
+    /* Example 1 (IOMMU device with wired interrupts) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu1: iommu@1bccd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
+                     <33 IRQ_TYPE_LEVEL_HIGH>,
+                     <34 IRQ_TYPE_LEVEL_HIGH>,
+                     <35 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+    /* Device with two IOMMU device IDs, 0 and 7 */
+    master1 {
+        iommus = <&iommu1 0>, <&iommu1 7>;
+    };
+
+  - |+
+    /* Example 2 (IOMMU device with shared wired interrupt) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu2: iommu@1bccd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 3 (IOMMU device with MSIs) */
+    iommu3: iommu@1bcdd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        msi-parent = <&imsics_smode>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 4 (IOMMU PCIe device with MSIs) */
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pcie@30000000 {
+            device_type = "pci";
+            #address-cells = <3>;
+            #size-cells = <2>;
+            reg = <0x0 0x30000000  0x0 0x1000000>;
+            ranges = <0x02000000 0x0 0x41000000  0x0 0x41000000  0x0 0x0f000000>;
+
+            /*
+             * The IOMMU manages all functions in this PCI domain except
+             * itself. Omit BDF 00:01.0.
+             */
+            iommu-map = <0x0 &iommu0 0x0 0x8>,
+                        <0x9 &iommu0 0x9 0xfff7>;
+
+            /* The IOMMU programming interface uses slot 00:01.0 */
+            iommu0: iommu@1,0 {
+               compatible = "pci1efd,edf1", "riscv,pci-iommu";
+               reg = <0x800 0 0 0 0>;
+               #iommu-cells = <1>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 28e20975c26f..7e090f878dc7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18957,6 +18957,13 @@ F:	arch/riscv/
 N:	riscv
 K:	riscv
 
+RISC-V IOMMU
+M:	Tomasz Jeznach <tjeznach@rivosinc.com>
+L:	iommu@lists.linux.dev
+L:	linux-riscv@lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
+
 RISC-V MICROCHIP FPGA SUPPORT
 M:	Conor Dooley <conor.dooley@microchip.com>
 M:	Daire McNamara <daire.mcnamara@microchip.com>
-- 
2.34.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[relevance 5%]

* [PATCH v4 1/3] bus: mhi: host: Add sysfs entry to force device to enter EDL
  @ 2024-04-23 10:33  5% ` Qiang Yu
  0 siblings, 0 replies; 200+ results
From: Qiang Yu @ 2024-04-23 10:33 UTC (permalink / raw)
  To: mani, quic_jhugo
  Cc: mhi, linux-arm-msm, linux-kernel, quic_cang, quic_mrana, Qiang Yu

Add sysfs entry to allow users of MHI bus force device to enter EDL.
Considering that the way to enter EDL mode varies from device to device and
some devices even do not support EDL. Hence, add a callback edl_trigger in
mhi controller as part of the sysfs entry to be invoked and MHI core will
only create EDL sysfs entry for mhi controller that provides edl_trigger
callback. All of the process a specific device required to enter EDL mode
can be placed in this callback.

Signed-off-by: Qiang Yu <quic_qianyu@quicinc.com>
---
 Documentation/ABI/stable/sysfs-bus-mhi | 13 +++++++++++++
 drivers/bus/mhi/host/init.c            | 33 +++++++++++++++++++++++++++++++++
 include/linux/mhi.h                    |  2 ++
 3 files changed, 48 insertions(+)

diff --git a/Documentation/ABI/stable/sysfs-bus-mhi b/Documentation/ABI/stable/sysfs-bus-mhi
index 1a47f9e..b44f467 100644
--- a/Documentation/ABI/stable/sysfs-bus-mhi
+++ b/Documentation/ABI/stable/sysfs-bus-mhi
@@ -29,3 +29,16 @@ Description:	Initiates a SoC reset on the MHI controller.  A SoC reset is
                 This can be useful as a method of recovery if the device is
                 non-responsive, or as a means of loading new firmware as a
                 system administration task.
+
+What:           /sys/bus/mhi/devices/.../trigger_edl
+Date:           April 2024
+KernelVersion:  6.9
+Contact:        mhi@lists.linux.dev
+Description:    Writing a non-zero value to this file will force devices to
+                enter EDL (Emergency Download) mode. This entry only exists for
+                devices capable of entering the EDL mode using the standard EDL
+                triggering mechanism defined in the MHI spec v1.2. Once in EDL
+                mode, the flash programmer image can be downloaded to the
+                device to enter the flash programmer execution environment.
+                This can be useful if user wants to use QDL (Qualcomm Download,
+                which is used to download firmware over EDL) to update firmware.
diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c
index 44f9349..7104c18 100644
--- a/drivers/bus/mhi/host/init.c
+++ b/drivers/bus/mhi/host/init.c
@@ -127,6 +127,30 @@ static ssize_t soc_reset_store(struct device *dev,
 }
 static DEVICE_ATTR_WO(soc_reset);
 
+static ssize_t trigger_edl_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct mhi_device *mhi_dev = to_mhi_device(dev);
+	struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+	unsigned long val;
+	int ret;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret < 0)
+		return ret;
+
+	if (!val)
+		return -EINVAL;
+
+	ret = mhi_cntrl->edl_trigger(mhi_cntrl);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static DEVICE_ATTR_WO(trigger_edl);
+
 static struct attribute *mhi_dev_attrs[] = {
 	&dev_attr_serial_number.attr,
 	&dev_attr_oem_pk_hash.attr,
@@ -1018,6 +1042,12 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
 	if (ret)
 		goto err_release_dev;
 
+	if (mhi_cntrl->edl_trigger) {
+		ret = sysfs_create_file(&mhi_dev->dev.kobj, &dev_attr_trigger_edl.attr);
+		if (ret)
+			goto err_release_dev;
+	}
+
 	mhi_cntrl->mhi_dev = mhi_dev;
 
 	mhi_create_debugfs(mhi_cntrl);
@@ -1051,6 +1081,9 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl)
 	mhi_deinit_free_irq(mhi_cntrl);
 	mhi_destroy_debugfs(mhi_cntrl);
 
+	if (mhi_cntrl->edl_trigger)
+		sysfs_remove_file(&mhi_dev->dev.kobj, &dev_attr_trigger_edl.attr);
+
 	destroy_workqueue(mhi_cntrl->hiprio_wq);
 	kfree(mhi_cntrl->mhi_cmd);
 	kfree(mhi_cntrl->mhi_event);
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index cde01e1..d968e1a 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -353,6 +353,7 @@ struct mhi_controller_config {
  * @read_reg: Read a MHI register via the physical link (required)
  * @write_reg: Write a MHI register via the physical link (required)
  * @reset: Controller specific reset function (optional)
+ * @edl_trigger: CB function to trigger EDL mode (optional)
  * @buffer_len: Bounce buffer length
  * @index: Index of the MHI controller instance
  * @bounce_buf: Use of bounce buffer
@@ -435,6 +436,7 @@ struct mhi_controller {
 	void (*write_reg)(struct mhi_controller *mhi_cntrl, void __iomem *addr,
 			  u32 val);
 	void (*reset)(struct mhi_controller *mhi_cntrl);
+	int (*edl_trigger)(struct mhi_controller *mhi_cntrl);
 
 	size_t buffer_len;
 	int index;
-- 
2.7.4


^ permalink raw reply related	[relevance 5%]

* [PATCH v12 1/2] spi: add loongson spi bindings
  @ 2023-06-08  7:28  5% ` Yinbo Zhu
  0 siblings, 0 replies; 200+ results
From: Yinbo Zhu @ 2023-06-08  7:28 UTC (permalink / raw)
  To: Mark Brown, Rob Herring, Krzysztof Kozlowski, linux-spi,
	devicetree, linux-kernel
  Cc: Jianmin Lv, wanghongliang, Liu Peibao, loongson-kernel, Yinbo Zhu,
	Krzysztof Kozlowski

Add the Loongson platform spi binding with DT schema format using
json-schema.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
 .../bindings/spi/loongson,ls2k-spi.yaml       | 41 +++++++++++++++++++
 MAINTAINERS                                   |  6 +++
 2 files changed, 47 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml

diff --git a/Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml b/Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml
new file mode 100644
index 000000000000..423ee851edd5
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/loongson,ls2k-spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson SPI controller
+
+maintainers:
+  - Yinbo Zhu <zhuyinbo@loongson.cn>
+
+allOf:
+  - $ref: /schemas/spi/spi-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - loongson,ls2k1000-spi
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    spi0: spi@1fff0220{
+        compatible = "loongson,ls2k1000-spi";
+        reg = <0x1fff0220 0x10>;
+        clocks = <&clk 17>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index bc201627c2e0..5e604dddd87b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12186,6 +12186,12 @@ F:	Documentation/devicetree/bindings/clock/loongson,ls2k-clk.yaml
 F:	drivers/clk/clk-loongson2.c
 F:	include/dt-bindings/clock/loongson,ls2k-clk.h
 
+LOONGSON SPI DRIVER
+M:	Yinbo Zhu <zhuyinbo@loongson.cn>
+L:	linux-spi@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml
+
 LOONGSON-2 SOC SERIES GUTS DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	loongarch@lists.linux.dev
-- 
2.20.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v2 2/2] dt-bindings: soc: add loongson2 guts
  2022-10-25  3:51  6% [PATCH v2 1/2] soc: loongson: add GUTS driver for loongson2 platforms Yinbo Zhu
@ 2022-10-25  3:51  5% ` Yinbo Zhu
  0 siblings, 0 replies; 200+ results
From: Yinbo Zhu @ 2022-10-25  3:51 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, Yinbo Zhu

Add the loongson2 soc guts driver binding with DT schema format
using json-schema.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
---
 .../soc/loongson/loongson,ls2k-guts.yaml      | 37 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/loongson/loongson,ls2k-guts.yaml

diff --git a/Documentation/devicetree/bindings/soc/loongson/loongson,ls2k-guts.yaml b/Documentation/devicetree/bindings/soc/loongson/loongson,ls2k-guts.yaml
new file mode 100644
index 000000000000..2502f8aeb74d
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/loongson/loongson,ls2k-guts.yaml
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/loongson/loongson,ls2k-guts.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson2 GUTS driver.
+
+maintainers:
+  - Yinbo Zhu <zhuyinbo@loongson.cn>
+
+description: |
+  GUTS driver was to manage and access global utilities block. Initially
+  only reading SVR and registering soc device are supported.
+
+properties:
+  compatible:
+    const: loongson,ls2k-guts
+
+  reg:
+    maxItems: 1
+
+  little-endian: true
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    guts: guts@1fe00000 {
+        compatible = "loongson,ls2k-guts";
+        reg = <0x1fe00000 0x3ffc>;
+        little-endian;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 0f06dc83f7c6..b23474a5d8c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11934,6 +11934,7 @@ LOONGSON2 SOC SERIES GUTS DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	loongarch@lists.linux.dev
 S:	Maintained
+F:	Documentation/devicetree/bindings/soc/loongson/loongson,ls2k-guts.yaml
 F:	drivers/soc/loongson/loongson2_guts.c
 
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
-- 
2.31.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v4 2/2] dt-bindings: soc: add loongson-2 chipid
  2022-11-02  3:55  6% [PATCH v4 1/2] soc: loongson: add GUTS driver for loongson-2 platforms Yinbo Zhu
@ 2022-11-02  3:55  5% ` Yinbo Zhu
  0 siblings, 0 replies; 200+ results
From: Yinbo Zhu @ 2022-11-02  3:55 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, Yinbo Zhu

Add the Loongson-2 SoC chipid binding with DT schema format using
json-schema.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
---
 .../bindings/hwinfo/loongson,ls2k-chipid.yaml | 38 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 39 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml

diff --git a/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
new file mode 100644
index 000000000000..9d0c36ec1982
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwinfo/loongson,ls2k-chipid.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson-2 SoC ChipID
+
+maintainers:
+  - Yinbo Zhu <zhuyinbo@loongson.cn>
+
+description: |
+  Loongson-2 SoC contains many groups of global utilities register
+  blocks, of which the ChipID group registers record SoC version,
+  feature, vendor and id information.
+
+properties:
+  compatible:
+    const: loongson,ls2k-chipid
+
+  reg:
+    maxItems: 1
+
+  little-endian: true
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    chipid: chipid@1fe00000 {
+        compatible = "loongson,ls2k-chipid";
+        reg = <0x1fe00000 0x3ffc>;
+        little-endian;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 20ce056ae207..916b2d9cffc0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12045,6 +12045,7 @@ LOONGSON-2 SOC SERIES GUTS DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	loongarch@lists.linux.dev
 S:	Maintained
+F:	Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
 F:	drivers/soc/loongson/loongson2_guts.c
 
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
-- 
2.33.0


^ permalink raw reply related	[relevance 5%]

* [PATCH v5 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU
@ 2024-05-14 18:16  5%   ` Tomasz Jeznach
  0 siblings, 0 replies; 200+ results
From: Tomasz Jeznach @ 2024-05-14 18:16 UTC (permalink / raw)
  To: Joerg Roedel, Will Deacon, Robin Murphy, Paul Walmsley
  Cc: Palmer Dabbelt, Albert Ou, Anup Patel, Sunil V L, Nick Kossifidis,
	Sebastien Boeuf, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	devicetree, iommu, linux-riscv, linux-kernel, linux,
	Tomasz Jeznach, Conor Dooley, Rob Herring

Add bindings for the RISC-V IOMMU device drivers.

Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com>
---
 .../bindings/iommu/riscv,iommu.yaml           | 147 ++++++++++++++++++
 MAINTAINERS                                   |   7 +
 2 files changed, 154 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/riscv,iommu.yaml

diff --git a/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
new file mode 100644
index 000000000000..5d015eeb06d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/riscv,iommu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V IOMMU Architecture Implementation
+
+maintainers:
+  - Tomasz Jeznach <tjeznach@rivosinc.com>
+
+description: |
+  The RISC-V IOMMU provides memory address translation and isolation for
+  input and output devices, supporting per-device translation context,
+  shared process address spaces including the ATS and PRI components of
+  the PCIe specification, two stage address translation and MSI remapping.
+  It supports identical translation table format to the RISC-V address
+  translation tables with page level access and protection attributes.
+  Hardware uses in-memory command and fault reporting queues with wired
+  interrupt or MSI notifications.
+
+  Visit https://github.com/riscv-non-isa/riscv-iommu for more details.
+
+  For information on assigning RISC-V IOMMU to its peripheral devices,
+  see generic IOMMU bindings.
+
+properties:
+  # For PCIe IOMMU hardware compatible property should contain the vendor
+  # and device ID according to the PCI Bus Binding specification.
+  # Since PCI provides built-in identification methods, compatible is not
+  # actually required. For non-PCIe hardware implementations 'riscv,iommu'
+  # should be specified along with 'reg' property providing MMIO location.
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - qemu,riscv-iommu
+          - const: riscv,iommu
+      - items:
+          - enum:
+              - pci1efd,edf1
+          - const: riscv,pci-iommu
+
+  reg:
+    maxItems: 1
+    description:
+      For non-PCI devices this represents base address and size of for the
+      IOMMU memory mapped registers interface.
+      For PCI IOMMU hardware implementation this should represent an address
+      of the IOMMU, as defined in the PCI Bus Binding reference.
+
+  '#iommu-cells':
+    const: 1
+    description:
+      The single cell describes the requester id emitted by a master to the
+      IOMMU.
+
+  interrupts:
+    minItems: 1
+    maxItems: 4
+    description:
+      Wired interrupt vectors available for RISC-V IOMMU to notify the
+      RISC-V HARTS. The cause to interrupt vector is software defined
+      using IVEC IOMMU register.
+
+  msi-parent: true
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - '#iommu-cells'
+
+additionalProperties: false
+
+examples:
+  - |+
+    /* Example 1 (IOMMU device with wired interrupts) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu1: iommu@1bccd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
+                     <33 IRQ_TYPE_LEVEL_HIGH>,
+                     <34 IRQ_TYPE_LEVEL_HIGH>,
+                     <35 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+    /* Device with two IOMMU device IDs, 0 and 7 */
+    master1 {
+        iommus = <&iommu1 0>, <&iommu1 7>;
+    };
+
+  - |+
+    /* Example 2 (IOMMU device with shared wired interrupt) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu2: iommu@1bccd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 3 (IOMMU device with MSIs) */
+    iommu3: iommu@1bcdd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        msi-parent = <&imsics_smode>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 4 (IOMMU PCIe device with MSIs) */
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pcie@30000000 {
+            device_type = "pci";
+            #address-cells = <3>;
+            #size-cells = <2>;
+            reg = <0x0 0x30000000  0x0 0x1000000>;
+            ranges = <0x02000000 0x0 0x41000000  0x0 0x41000000  0x0 0x0f000000>;
+
+            /*
+             * The IOMMU manages all functions in this PCI domain except
+             * itself. Omit BDF 00:01.0.
+             */
+            iommu-map = <0x0 &iommu0 0x0 0x8>,
+                        <0x9 &iommu0 0x9 0xfff7>;
+
+            /* The IOMMU programming interface uses slot 00:01.0 */
+            iommu0: iommu@1,0 {
+               compatible = "pci1efd,edf1", "riscv,pci-iommu";
+               reg = <0x800 0 0 0 0>;
+               #iommu-cells = <1>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 28e20975c26f..7e090f878dc7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18957,6 +18957,13 @@ F:	arch/riscv/
 N:	riscv
 K:	riscv
 
+RISC-V IOMMU
+M:	Tomasz Jeznach <tjeznach@rivosinc.com>
+L:	iommu@lists.linux.dev
+L:	linux-riscv@lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
+
 RISC-V MICROCHIP FPGA SUPPORT
 M:	Conor Dooley <conor.dooley@microchip.com>
 M:	Daire McNamara <daire.mcnamara@microchip.com>
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v2 1/4] dt-bindings: pwm: Add Apple PWM controller
  @ 2022-11-02 14:15  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-11-02 14:15 UTC (permalink / raw)
  To: thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.3


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v4 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU
  @ 2024-05-03 16:12  5%   ` Tomasz Jeznach
  0 siblings, 0 replies; 200+ results
From: Tomasz Jeznach @ 2024-05-03 16:12 UTC (permalink / raw)
  To: Joerg Roedel, Will Deacon, Robin Murphy, Paul Walmsley
  Cc: Anup Patel, devicetree, Conor Dooley, Albert Ou, Tomasz Jeznach,
	linux, Conor Dooley, linux-kernel, Rob Herring, Sebastien Boeuf,
	iommu, Palmer Dabbelt, Nick Kossifidis, Krzysztof Kozlowski,
	linux-riscv

Add bindings for the RISC-V IOMMU device drivers.

Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com>
---
 .../bindings/iommu/riscv,iommu.yaml           | 147 ++++++++++++++++++
 MAINTAINERS                                   |   7 +
 2 files changed, 154 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/riscv,iommu.yaml

diff --git a/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
new file mode 100644
index 000000000000..5d015eeb06d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/riscv,iommu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V IOMMU Architecture Implementation
+
+maintainers:
+  - Tomasz Jeznach <tjeznach@rivosinc.com>
+
+description: |
+  The RISC-V IOMMU provides memory address translation and isolation for
+  input and output devices, supporting per-device translation context,
+  shared process address spaces including the ATS and PRI components of
+  the PCIe specification, two stage address translation and MSI remapping.
+  It supports identical translation table format to the RISC-V address
+  translation tables with page level access and protection attributes.
+  Hardware uses in-memory command and fault reporting queues with wired
+  interrupt or MSI notifications.
+
+  Visit https://github.com/riscv-non-isa/riscv-iommu for more details.
+
+  For information on assigning RISC-V IOMMU to its peripheral devices,
+  see generic IOMMU bindings.
+
+properties:
+  # For PCIe IOMMU hardware compatible property should contain the vendor
+  # and device ID according to the PCI Bus Binding specification.
+  # Since PCI provides built-in identification methods, compatible is not
+  # actually required. For non-PCIe hardware implementations 'riscv,iommu'
+  # should be specified along with 'reg' property providing MMIO location.
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - qemu,riscv-iommu
+          - const: riscv,iommu
+      - items:
+          - enum:
+              - pci1efd,edf1
+          - const: riscv,pci-iommu
+
+  reg:
+    maxItems: 1
+    description:
+      For non-PCI devices this represents base address and size of for the
+      IOMMU memory mapped registers interface.
+      For PCI IOMMU hardware implementation this should represent an address
+      of the IOMMU, as defined in the PCI Bus Binding reference.
+
+  '#iommu-cells':
+    const: 1
+    description:
+      The single cell describes the requester id emitted by a master to the
+      IOMMU.
+
+  interrupts:
+    minItems: 1
+    maxItems: 4
+    description:
+      Wired interrupt vectors available for RISC-V IOMMU to notify the
+      RISC-V HARTS. The cause to interrupt vector is software defined
+      using IVEC IOMMU register.
+
+  msi-parent: true
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - '#iommu-cells'
+
+additionalProperties: false
+
+examples:
+  - |+
+    /* Example 1 (IOMMU device with wired interrupts) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu1: iommu@1bccd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
+                     <33 IRQ_TYPE_LEVEL_HIGH>,
+                     <34 IRQ_TYPE_LEVEL_HIGH>,
+                     <35 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+    /* Device with two IOMMU device IDs, 0 and 7 */
+    master1 {
+        iommus = <&iommu1 0>, <&iommu1 7>;
+    };
+
+  - |+
+    /* Example 2 (IOMMU device with shared wired interrupt) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu2: iommu@1bccd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 3 (IOMMU device with MSIs) */
+    iommu3: iommu@1bcdd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        msi-parent = <&imsics_smode>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 4 (IOMMU PCIe device with MSIs) */
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pcie@30000000 {
+            device_type = "pci";
+            #address-cells = <3>;
+            #size-cells = <2>;
+            reg = <0x0 0x30000000  0x0 0x1000000>;
+            ranges = <0x02000000 0x0 0x41000000  0x0 0x41000000  0x0 0x0f000000>;
+
+            /*
+             * The IOMMU manages all functions in this PCI domain except
+             * itself. Omit BDF 00:01.0.
+             */
+            iommu-map = <0x0 &iommu0 0x0 0x8>,
+                        <0x9 &iommu0 0x9 0xfff7>;
+
+            /* The IOMMU programming interface uses slot 00:01.0 */
+            iommu0: iommu@1,0 {
+               compatible = "pci1efd,edf1", "riscv,pci-iommu";
+               reg = <0x800 0 0 0 0>;
+               #iommu-cells = <1>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index f6dc90559341..7fcf7c27ef6b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18958,6 +18958,13 @@ F:	arch/riscv/
 N:	riscv
 K:	riscv
 
+RISC-V IOMMU
+M:	Tomasz Jeznach <tjeznach@rivosinc.com>
+L:	iommu@lists.linux.dev
+L:	linux-riscv@lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
+
 RISC-V MICROCHIP FPGA SUPPORT
 M:	Conor Dooley <conor.dooley@microchip.com>
 M:	Daire McNamara <daire.mcnamara@microchip.com>
-- 
2.34.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[relevance 5%]

* [merged mm-stable] mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message.patch removed from -mm tree
@ 2023-02-13 23:55  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2023-02-13 23:55 UTC (permalink / raw)
  To: mm-commits, corbet, sj, akpm


The quilt patch titled
     Subject: mm/damon/dbgfs: print DAMON debugfs interface deprecation message
has been removed from the -mm tree.  Its filename was
     mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message.patch

This patch was dropped because it was merged into the mm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: mm/damon/dbgfs: print DAMON debugfs interface deprecation message
Date: Thu, 9 Feb 2023 19:20:09 +0000

DAMON debugfs interface has announced to be deprecated after >v5.15 LTS
kernel is released.  And, v6.1.y has announced to be an LTS[1].

Though the announcement was there for a while, some people might not
noticed that so far.  Also, some users could depend on it and have
problems at  movng to the alternative (DAMON sysfs interface).

For such cases, warn DAMON debugfs interface deprecation with contacts
to ask helps when any DAMON debugfs interface file is opened.

[1] https://git.kernel.org/pub/scm/docs/kernel/website.git/commit/?id=332e9121320bc7461b2d3a79665caf153e51732c

[sj@kernel.org: split DAMON debugfs file open warning message, per Randy]
  Link: https://lkml.kernel.org/r/20230209192009.7885-4-sj@kernel.org
  Link: https://lkml.kernel.org/r/20230210044838.63723-4-sj@kernel.org
Link: https://lkml.kernel.org/r/20230209192009.7885-4-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---


--- a/mm/damon/dbgfs.c~mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message
+++ a/mm/damon/dbgfs.c
@@ -20,6 +20,14 @@ static int dbgfs_nr_ctxs;
 static struct dentry **dbgfs_dirs;
 static DEFINE_MUTEX(damon_dbgfs_lock);
 
+static void damon_dbgfs_warn_deprecation(void)
+{
+	pr_warn_once("DAMON debugfs interface is deprecated, "
+		     "so users should move to DAMON_SYSFS. If you cannot, "
+		     "please report your usecase to damon@lists.linux.dev and "
+		     "linux-mm@kvack.org.\n");
+}
+
 /*
  * Returns non-empty string on success, negative error code otherwise.
  */
@@ -711,6 +719,8 @@ out:
 
 static int damon_dbgfs_open(struct inode *inode, struct file *file)
 {
+	damon_dbgfs_warn_deprecation();
+
 	file->private_data = inode->i_private;
 
 	return nonseekable_open(inode, file);
@@ -1039,15 +1049,24 @@ static ssize_t dbgfs_monitor_on_write(st
 	return ret;
 }
 
+static int damon_dbgfs_static_file_open(struct inode *inode, struct file *file)
+{
+	damon_dbgfs_warn_deprecation();
+	return nonseekable_open(inode, file);
+}
+
 static const struct file_operations mk_contexts_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.write = dbgfs_mk_context_write,
 };
 
 static const struct file_operations rm_contexts_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.write = dbgfs_rm_context_write,
 };
 
 static const struct file_operations monitor_on_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.read = dbgfs_monitor_on_read,
 	.write = dbgfs_monitor_on_write,
 };
_

Patches currently in -mm which might be from sj@kernel.org are



^ permalink raw reply	[relevance 5%]

* [PATCH v4 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU
@ 2024-05-03 16:12  5%   ` Tomasz Jeznach
  0 siblings, 0 replies; 200+ results
From: Tomasz Jeznach @ 2024-05-03 16:12 UTC (permalink / raw)
  To: Joerg Roedel, Will Deacon, Robin Murphy, Paul Walmsley
  Cc: Palmer Dabbelt, Albert Ou, Anup Patel, Sunil V L, Nick Kossifidis,
	Sebastien Boeuf, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	devicetree, iommu, linux-riscv, linux-kernel, linux,
	Tomasz Jeznach, Conor Dooley

Add bindings for the RISC-V IOMMU device drivers.

Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com>
---
 .../bindings/iommu/riscv,iommu.yaml           | 147 ++++++++++++++++++
 MAINTAINERS                                   |   7 +
 2 files changed, 154 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/riscv,iommu.yaml

diff --git a/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
new file mode 100644
index 000000000000..5d015eeb06d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/riscv,iommu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V IOMMU Architecture Implementation
+
+maintainers:
+  - Tomasz Jeznach <tjeznach@rivosinc.com>
+
+description: |
+  The RISC-V IOMMU provides memory address translation and isolation for
+  input and output devices, supporting per-device translation context,
+  shared process address spaces including the ATS and PRI components of
+  the PCIe specification, two stage address translation and MSI remapping.
+  It supports identical translation table format to the RISC-V address
+  translation tables with page level access and protection attributes.
+  Hardware uses in-memory command and fault reporting queues with wired
+  interrupt or MSI notifications.
+
+  Visit https://github.com/riscv-non-isa/riscv-iommu for more details.
+
+  For information on assigning RISC-V IOMMU to its peripheral devices,
+  see generic IOMMU bindings.
+
+properties:
+  # For PCIe IOMMU hardware compatible property should contain the vendor
+  # and device ID according to the PCI Bus Binding specification.
+  # Since PCI provides built-in identification methods, compatible is not
+  # actually required. For non-PCIe hardware implementations 'riscv,iommu'
+  # should be specified along with 'reg' property providing MMIO location.
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - qemu,riscv-iommu
+          - const: riscv,iommu
+      - items:
+          - enum:
+              - pci1efd,edf1
+          - const: riscv,pci-iommu
+
+  reg:
+    maxItems: 1
+    description:
+      For non-PCI devices this represents base address and size of for the
+      IOMMU memory mapped registers interface.
+      For PCI IOMMU hardware implementation this should represent an address
+      of the IOMMU, as defined in the PCI Bus Binding reference.
+
+  '#iommu-cells':
+    const: 1
+    description:
+      The single cell describes the requester id emitted by a master to the
+      IOMMU.
+
+  interrupts:
+    minItems: 1
+    maxItems: 4
+    description:
+      Wired interrupt vectors available for RISC-V IOMMU to notify the
+      RISC-V HARTS. The cause to interrupt vector is software defined
+      using IVEC IOMMU register.
+
+  msi-parent: true
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - '#iommu-cells'
+
+additionalProperties: false
+
+examples:
+  - |+
+    /* Example 1 (IOMMU device with wired interrupts) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu1: iommu@1bccd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
+                     <33 IRQ_TYPE_LEVEL_HIGH>,
+                     <34 IRQ_TYPE_LEVEL_HIGH>,
+                     <35 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+    /* Device with two IOMMU device IDs, 0 and 7 */
+    master1 {
+        iommus = <&iommu1 0>, <&iommu1 7>;
+    };
+
+  - |+
+    /* Example 2 (IOMMU device with shared wired interrupt) */
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    iommu2: iommu@1bccd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        interrupt-parent = <&aplic_smode>;
+        interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 3 (IOMMU device with MSIs) */
+    iommu3: iommu@1bcdd000 {
+        compatible = "qemu,riscv-iommu", "riscv,iommu";
+        reg = <0x1bccd000 0x1000>;
+        msi-parent = <&imsics_smode>;
+        #iommu-cells = <1>;
+    };
+
+  - |+
+    /* Example 4 (IOMMU PCIe device with MSIs) */
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pcie@30000000 {
+            device_type = "pci";
+            #address-cells = <3>;
+            #size-cells = <2>;
+            reg = <0x0 0x30000000  0x0 0x1000000>;
+            ranges = <0x02000000 0x0 0x41000000  0x0 0x41000000  0x0 0x0f000000>;
+
+            /*
+             * The IOMMU manages all functions in this PCI domain except
+             * itself. Omit BDF 00:01.0.
+             */
+            iommu-map = <0x0 &iommu0 0x0 0x8>,
+                        <0x9 &iommu0 0x9 0xfff7>;
+
+            /* The IOMMU programming interface uses slot 00:01.0 */
+            iommu0: iommu@1,0 {
+               compatible = "pci1efd,edf1", "riscv,pci-iommu";
+               reg = <0x800 0 0 0 0>;
+               #iommu-cells = <1>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index f6dc90559341..7fcf7c27ef6b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18958,6 +18958,13 @@ F:	arch/riscv/
 N:	riscv
 K:	riscv
 
+RISC-V IOMMU
+M:	Tomasz Jeznach <tjeznach@rivosinc.com>
+L:	iommu@lists.linux.dev
+L:	linux-riscv@lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
+
 RISC-V MICROCHIP FPGA SUPPORT
 M:	Conor Dooley <conor.dooley@microchip.com>
 M:	Daire McNamara <daire.mcnamara@microchip.com>
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH 1/4] dt-bindings: pwm: Add Apple PWM controller
  @ 2022-10-28 16:52  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-10-28 16:52 UTC (permalink / raw)
  To: thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
---
 .../devicetree/bindings/pwm/pwm-apple.yaml    | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-apple.yaml

diff --git a/Documentation/devicetree/bindings/pwm/pwm-apple.yaml b/Documentation/devicetree/bindings/pwm/pwm-apple.yaml
new file mode 100644
index 000000000000..39dc32e00a3f
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-apple.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/pwm-apple.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: |+
+  PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm: fpwm@235044000 {
+      compatible = "apple,s5l-fpwm";
+      reg = <0x2 0x35044000 0x0 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.3


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* + maintainers-add-self-as-clang-reviewer.patch added to -mm tree
@ 2022-04-07 20:51  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2022-04-07 20:51 UTC (permalink / raw)
  To: mm-commits, ndesaulniers, nathan, trix, akpm


The patch titled
     Subject: MAINTAINERS: add Tom as clang reviewer
has been added to the -mm tree.  Its filename is
     maintainers-add-self-as-clang-reviewer.patch

This patch should soon appear at
    https://ozlabs.org/~akpm/mmots/broken-out/maintainers-add-self-as-clang-reviewer.patch
and later at
    https://ozlabs.org/~akpm/mmotm/broken-out/maintainers-add-self-as-clang-reviewer.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next and is updated
there every 3-4 working days

------------------------------------------------------
From: Tom Rix <trix@redhat.com>
Subject: MAINTAINERS: add Tom as clang reviewer

I have been helping with build breaks and other clang things and would
like to help with the reviews.

Link: https://lkml.kernel.org/r/20220407175715.3378998-1-trix@redhat.com
Signed-off-by: Tom Rix <trix@redhat.com>
Acked-by: Nathan Chancellor <nathan@kernel.org>
Acked-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 MAINTAINERS |    1 +
 1 file changed, 1 insertion(+)

--- a/MAINTAINERS~maintainers-add-self-as-clang-reviewer
+++ a/MAINTAINERS
@@ -4791,6 +4791,7 @@ F:	.clang-format
 CLANG/LLVM BUILD SUPPORT
 M:	Nathan Chancellor <nathan@kernel.org>
 M:	Nick Desaulniers <ndesaulniers@google.com>
+R:	Tom Rix <trix@redhat.com>
 L:	llvm@lists.linux.dev
 S:	Supported
 W:	https://clangbuiltlinux.github.io/
_

Patches currently in -mm which might be from trix@redhat.com are

maintainers-add-self-as-clang-reviewer.patch
lib-remove-back_str-initialization.patch


^ permalink raw reply	[relevance 5%]

* [PATCH v2 1/4] dt-bindings: pwm: Add Apple PWM controller
@ 2022-11-02 14:15  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-11-02 14:15 UTC (permalink / raw)
  To: thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
---
 .../bindings/pwm/apple,s5l-fpwm.yaml          | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644
index 000000000000..142157bff0cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.3


^ permalink raw reply related	[relevance 5%]

* [PATCH v3] powerpc/papr_scm: Implement initial support for injecting smart errors
@ 2022-01-13 12:02  5% ` Vaibhav Jain
  0 siblings, 0 replies; 200+ results
From: Vaibhav Jain @ 2022-01-13 12:02 UTC (permalink / raw)
  To: nvdimm, linuxppc-dev
  Cc: Vaibhav Jain, Dan Williams, Aneesh Kumar K . V, Michael Ellerman,
	Ira Weiny, Shivaprasad G Bhat

Presently PAPR doesn't support injecting smart errors on an
NVDIMM. This makes testing the NVDIMM health reporting functionality
difficult as simulating NVDIMM health related events need a hacked up
qemu version.

To solve this problem this patch proposes simulating certain set of
NVDIMM health related events in papr_scm. Specifically 'fatal' health
state and 'dirty' shutdown state. These error can be injected via the
user-space 'ndctl-inject-smart(1)' command. With the proposed patch and
corresponding ndctl patches following command flow is expected:

$ sudo ndctl list -DH -d nmem0
...
      "health_state":"ok",
      "shutdown_state":"clean",
...
 # inject unsafe shutdown and fatal health error
$ sudo ndctl inject-smart nmem0 -Uf
...
      "health_state":"fatal",
      "shutdown_state":"dirty",
...
 # uninject all errors
$ sudo ndctl inject-smart nmem0 -N
...
      "health_state":"ok",
      "shutdown_state":"clean",
...

The patch adds two members 'health_bitmap_mask' and
'health_bitmap_override' inside struct papr_scm_priv which are then
bit blt'ed to the health bitmaps fetched from the hypervisor. In case
we are not able to fetch health information from the hypervisor we
service the health bitmap from these two members. These members are
accessible from sysfs at nmemX/papr/health_bitmap_override

A new PDSM named 'SMART_INJECT' is proposed that accepts newly
introduced 'struct nd_papr_pdsm_smart_inject' as payload thats
exchanged between libndctl and papr_scm to indicate the requested
smart-error states.

When the processing the PDSM 'SMART_INJECT', papr_pdsm_smart_inject()
constructs a pair or 'mask' and 'override' bitmaps from the payload
and bit-blt it to the 'health_bitmap_{mask, override}' members. This
ensures the after being fetched from the hypervisor, the health_bitmap
reflects requested smart-error states.

Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
---
Changelog:

Since v2:
* Rebased the patch to ppc-next
* Added documentation for newly introduced sysfs attribute 'health_bitmap_override'

Since v1:
* Updated the patch description.
* Removed dependency of a header movement patch.
* Removed '__packed' attribute for 'struct nd_papr_pdsm_smart_inject' [Aneesh]
---
 Documentation/ABI/testing/sysfs-bus-papr-pmem | 13 +++
 arch/powerpc/include/uapi/asm/papr_pdsm.h     | 18 ++++
 arch/powerpc/platforms/pseries/papr_scm.c     | 94 ++++++++++++++++++-
 3 files changed, 122 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem
index 95254cec92bf..8a0b2a7f7671 100644
--- a/Documentation/ABI/testing/sysfs-bus-papr-pmem
+++ b/Documentation/ABI/testing/sysfs-bus-papr-pmem
@@ -61,3 +61,16 @@ Description:
 		* "CchRHCnt" : Cache Read Hit Count
 		* "CchWHCnt" : Cache Write Hit Count
 		* "FastWCnt" : Fast Write Count
+
+What:		/sys/bus/nd/devices/nmemX/papr/health_bitmap_override
+Date:		Jan, 2022
+KernelVersion:	v5.17
+Contact:	linuxppc-dev <linuxppc-dev@lists.ozlabs.org>, nvdimm@lists.linux.dev,
+Description:
+		(RO) Reports the health bitmap override/mask bitmaps that are
+		applied to top bitmap received from PowerVM via the H_SCM_HEALTH
+		Hcall. Together these can be used to forcibly set/reset specific
+		bits returned from Hcall. These bitmaps are presently used to
+		simulate various health or shutdown states for an nvdimm and are
+		set by user-space tools like ndctl by issuing a PAPR DSM.
+
diff --git a/arch/powerpc/include/uapi/asm/papr_pdsm.h b/arch/powerpc/include/uapi/asm/papr_pdsm.h
index 82488b1e7276..17439925045c 100644
--- a/arch/powerpc/include/uapi/asm/papr_pdsm.h
+++ b/arch/powerpc/include/uapi/asm/papr_pdsm.h
@@ -116,6 +116,22 @@ struct nd_papr_pdsm_health {
 	};
 };
 
+/* Flags for injecting specific smart errors */
+#define PDSM_SMART_INJECT_HEALTH_FATAL		(1 << 0)
+#define PDSM_SMART_INJECT_BAD_SHUTDOWN		(1 << 1)
+
+struct nd_papr_pdsm_smart_inject {
+	union {
+		struct {
+			/* One or more of PDSM_SMART_INJECT_ */
+			__u32 flags;
+			__u8 fatal_enable;
+			__u8 unsafe_shutdown_enable;
+		};
+		__u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
+	};
+};
+
 /*
  * Methods to be embedded in ND_CMD_CALL request. These are sent to the kernel
  * via 'nd_cmd_pkg.nd_command' member of the ioctl struct
@@ -123,12 +139,14 @@ struct nd_papr_pdsm_health {
 enum papr_pdsm {
 	PAPR_PDSM_MIN = 0x0,
 	PAPR_PDSM_HEALTH,
+	PAPR_PDSM_SMART_INJECT,
 	PAPR_PDSM_MAX,
 };
 
 /* Maximal union that can hold all possible payload types */
 union nd_pdsm_payload {
 	struct nd_papr_pdsm_health health;
+	struct nd_papr_pdsm_smart_inject smart_inject;
 	__u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
 } __packed;
 
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index f48e87ac89c9..de4cf329cfb3 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -68,6 +68,10 @@
 #define PAPR_SCM_PERF_STATS_EYECATCHER __stringify(SCMSTATS)
 #define PAPR_SCM_PERF_STATS_VERSION 0x1
 
+/* Use bitblt method to override specific bits in the '_bitmap_' */
+#define BITBLT_BITMAP(_bitmap_, _mask_, _override_)		\
+	(((_bitmap_) & ~(_mask_)) | ((_mask_) & (_override_)))
+
 /* Struct holding a single performance metric */
 struct papr_scm_perf_stat {
 	u8 stat_id[8];
@@ -120,6 +124,12 @@ struct papr_scm_priv {
 
 	/* length of the stat buffer as expected by phyp */
 	size_t stat_buffer_len;
+
+	/* The bits which needs to be overridden */
+	u64 health_bitmap_mask;
+
+	/* The overridden values for the bits having the masks set */
+	u64 health_bitmap_override;
 };
 
 static int papr_scm_pmem_flush(struct nd_region *nd_region,
@@ -347,19 +357,28 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p,
 static int __drc_pmem_query_health(struct papr_scm_priv *p)
 {
 	unsigned long ret[PLPAR_HCALL_BUFSIZE];
+	u64 bitmap = 0;
 	long rc;
 
 	/* issue the hcall */
 	rc = plpar_hcall(H_SCM_HEALTH, ret, p->drc_index);
-	if (rc != H_SUCCESS) {
+	if (rc == H_SUCCESS)
+		bitmap = ret[0] & ret[1];
+	else if (rc == H_FUNCTION)
+		dev_info_once(&p->pdev->dev,
+			      "Hcall H_SCM_HEALTH not implemented, assuming empty health bitmap");
+	else {
+
 		dev_err(&p->pdev->dev,
 			"Failed to query health information, Err:%ld\n", rc);
 		return -ENXIO;
 	}
 
 	p->lasthealth_jiffies = jiffies;
-	p->health_bitmap = ret[0] & ret[1];
-
+	/* Allow overriding specific health bits via bit blt. */
+	bitmap = BITBLT_BITMAP(bitmap, p->health_bitmap_mask,
+			       p->health_bitmap_override);
+	WRITE_ONCE(p->health_bitmap, bitmap);
 	dev_dbg(&p->pdev->dev,
 		"Queried dimm health info. Bitmap:0x%016lx Mask:0x%016lx\n",
 		ret[0], ret[1]);
@@ -669,6 +688,54 @@ static int papr_pdsm_health(struct papr_scm_priv *p,
 	return rc;
 }
 
+/* Inject a smart error Add the dirty-shutdown-counter value to the pdsm */
+static int papr_pdsm_smart_inject(struct papr_scm_priv *p,
+				  union nd_pdsm_payload *payload)
+{
+	int rc;
+	u32 supported_flags = 0;
+	u64 mask = 0, override = 0;
+
+	/* Check for individual smart error flags and update mask and override */
+	if (payload->smart_inject.flags & PDSM_SMART_INJECT_HEALTH_FATAL) {
+		supported_flags |= PDSM_SMART_INJECT_HEALTH_FATAL;
+		mask |= PAPR_PMEM_HEALTH_FATAL;
+		override |= payload->smart_inject.fatal_enable ?
+			PAPR_PMEM_HEALTH_FATAL : 0;
+	}
+
+	if (payload->smart_inject.flags & PDSM_SMART_INJECT_BAD_SHUTDOWN) {
+		supported_flags |= PDSM_SMART_INJECT_BAD_SHUTDOWN;
+		mask |= PAPR_PMEM_SHUTDOWN_DIRTY;
+		override |= payload->smart_inject.unsafe_shutdown_enable ?
+			PAPR_PMEM_SHUTDOWN_DIRTY : 0;
+	}
+
+	dev_dbg(&p->pdev->dev, "[Smart-inject] Mask=%#llx override=%#llx\n",
+		mask, override);
+
+	/* Prevent concurrent access to dimm health bitmap related members */
+	rc = mutex_lock_interruptible(&p->health_mutex);
+	if (rc)
+		return rc;
+
+	/* Bitblt mask/override to corrosponding health_bitmap couterparts */
+	p->health_bitmap_mask = BITBLT_BITMAP(p->health_bitmap_mask,
+					      mask, override);
+	p->health_bitmap_override = BITBLT_BITMAP(p->health_bitmap_override,
+						  mask, override);
+
+	/* Invalidate cached health bitmap */
+	p->lasthealth_jiffies = 0;
+
+	mutex_unlock(&p->health_mutex);
+
+	/* Return the supported flags back to userspace */
+	payload->smart_inject.flags = supported_flags;
+
+	return sizeof(struct nd_papr_pdsm_health);
+}
+
 /*
  * 'struct pdsm_cmd_desc'
  * Identifies supported PDSMs' expected length of in/out payloads
@@ -702,6 +769,12 @@ static const struct pdsm_cmd_desc __pdsm_cmd_descriptors[] = {
 		.size_out = sizeof(struct nd_papr_pdsm_health),
 		.service = papr_pdsm_health,
 	},
+
+	[PAPR_PDSM_SMART_INJECT] = {
+		.size_in = sizeof(struct nd_papr_pdsm_smart_inject),
+		.size_out = sizeof(struct nd_papr_pdsm_smart_inject),
+		.service = papr_pdsm_smart_inject,
+	},
 	/* Empty */
 	[PAPR_PDSM_MAX] = {
 		.size_in = 0,
@@ -838,6 +911,20 @@ static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc,
 	return 0;
 }
 
+static ssize_t health_bitmap_override_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct nvdimm *dimm = to_nvdimm(dev);
+	struct papr_scm_priv *p = nvdimm_provider_data(dimm);
+
+	return sprintf(buf, "mask=%#llx override=%#llx\n",
+		       READ_ONCE(p->health_bitmap_mask),
+		       READ_ONCE(p->health_bitmap_override));
+}
+
+static DEVICE_ATTR_ADMIN_RO(health_bitmap_override);
+
 static ssize_t perf_stats_show(struct device *dev,
 			       struct device_attribute *attr, char *buf)
 {
@@ -952,6 +1039,7 @@ static struct attribute *papr_nd_attributes[] = {
 	&dev_attr_flags.attr,
 	&dev_attr_perf_stats.attr,
 	&dev_attr_dirty_shutdown.attr,
+	&dev_attr_health_bitmap_override.attr,
 	NULL,
 };
 
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v3] powerpc/papr_scm: Implement initial support for injecting smart errors
@ 2022-01-13 12:02  5% ` Vaibhav Jain
  0 siblings, 0 replies; 200+ results
From: Vaibhav Jain @ 2022-01-13 12:02 UTC (permalink / raw)
  To: nvdimm, linuxppc-dev
  Cc: Shivaprasad G Bhat, Aneesh Kumar K . V, Vaibhav Jain,
	Dan Williams, Ira Weiny

Presently PAPR doesn't support injecting smart errors on an
NVDIMM. This makes testing the NVDIMM health reporting functionality
difficult as simulating NVDIMM health related events need a hacked up
qemu version.

To solve this problem this patch proposes simulating certain set of
NVDIMM health related events in papr_scm. Specifically 'fatal' health
state and 'dirty' shutdown state. These error can be injected via the
user-space 'ndctl-inject-smart(1)' command. With the proposed patch and
corresponding ndctl patches following command flow is expected:

$ sudo ndctl list -DH -d nmem0
...
      "health_state":"ok",
      "shutdown_state":"clean",
...
 # inject unsafe shutdown and fatal health error
$ sudo ndctl inject-smart nmem0 -Uf
...
      "health_state":"fatal",
      "shutdown_state":"dirty",
...
 # uninject all errors
$ sudo ndctl inject-smart nmem0 -N
...
      "health_state":"ok",
      "shutdown_state":"clean",
...

The patch adds two members 'health_bitmap_mask' and
'health_bitmap_override' inside struct papr_scm_priv which are then
bit blt'ed to the health bitmaps fetched from the hypervisor. In case
we are not able to fetch health information from the hypervisor we
service the health bitmap from these two members. These members are
accessible from sysfs at nmemX/papr/health_bitmap_override

A new PDSM named 'SMART_INJECT' is proposed that accepts newly
introduced 'struct nd_papr_pdsm_smart_inject' as payload thats
exchanged between libndctl and papr_scm to indicate the requested
smart-error states.

When the processing the PDSM 'SMART_INJECT', papr_pdsm_smart_inject()
constructs a pair or 'mask' and 'override' bitmaps from the payload
and bit-blt it to the 'health_bitmap_{mask, override}' members. This
ensures the after being fetched from the hypervisor, the health_bitmap
reflects requested smart-error states.

Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
---
Changelog:

Since v2:
* Rebased the patch to ppc-next
* Added documentation for newly introduced sysfs attribute 'health_bitmap_override'

Since v1:
* Updated the patch description.
* Removed dependency of a header movement patch.
* Removed '__packed' attribute for 'struct nd_papr_pdsm_smart_inject' [Aneesh]
---
 Documentation/ABI/testing/sysfs-bus-papr-pmem | 13 +++
 arch/powerpc/include/uapi/asm/papr_pdsm.h     | 18 ++++
 arch/powerpc/platforms/pseries/papr_scm.c     | 94 ++++++++++++++++++-
 3 files changed, 122 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem
index 95254cec92bf..8a0b2a7f7671 100644
--- a/Documentation/ABI/testing/sysfs-bus-papr-pmem
+++ b/Documentation/ABI/testing/sysfs-bus-papr-pmem
@@ -61,3 +61,16 @@ Description:
 		* "CchRHCnt" : Cache Read Hit Count
 		* "CchWHCnt" : Cache Write Hit Count
 		* "FastWCnt" : Fast Write Count
+
+What:		/sys/bus/nd/devices/nmemX/papr/health_bitmap_override
+Date:		Jan, 2022
+KernelVersion:	v5.17
+Contact:	linuxppc-dev <linuxppc-dev@lists.ozlabs.org>, nvdimm@lists.linux.dev,
+Description:
+		(RO) Reports the health bitmap override/mask bitmaps that are
+		applied to top bitmap received from PowerVM via the H_SCM_HEALTH
+		Hcall. Together these can be used to forcibly set/reset specific
+		bits returned from Hcall. These bitmaps are presently used to
+		simulate various health or shutdown states for an nvdimm and are
+		set by user-space tools like ndctl by issuing a PAPR DSM.
+
diff --git a/arch/powerpc/include/uapi/asm/papr_pdsm.h b/arch/powerpc/include/uapi/asm/papr_pdsm.h
index 82488b1e7276..17439925045c 100644
--- a/arch/powerpc/include/uapi/asm/papr_pdsm.h
+++ b/arch/powerpc/include/uapi/asm/papr_pdsm.h
@@ -116,6 +116,22 @@ struct nd_papr_pdsm_health {
 	};
 };
 
+/* Flags for injecting specific smart errors */
+#define PDSM_SMART_INJECT_HEALTH_FATAL		(1 << 0)
+#define PDSM_SMART_INJECT_BAD_SHUTDOWN		(1 << 1)
+
+struct nd_papr_pdsm_smart_inject {
+	union {
+		struct {
+			/* One or more of PDSM_SMART_INJECT_ */
+			__u32 flags;
+			__u8 fatal_enable;
+			__u8 unsafe_shutdown_enable;
+		};
+		__u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
+	};
+};
+
 /*
  * Methods to be embedded in ND_CMD_CALL request. These are sent to the kernel
  * via 'nd_cmd_pkg.nd_command' member of the ioctl struct
@@ -123,12 +139,14 @@ struct nd_papr_pdsm_health {
 enum papr_pdsm {
 	PAPR_PDSM_MIN = 0x0,
 	PAPR_PDSM_HEALTH,
+	PAPR_PDSM_SMART_INJECT,
 	PAPR_PDSM_MAX,
 };
 
 /* Maximal union that can hold all possible payload types */
 union nd_pdsm_payload {
 	struct nd_papr_pdsm_health health;
+	struct nd_papr_pdsm_smart_inject smart_inject;
 	__u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
 } __packed;
 
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index f48e87ac89c9..de4cf329cfb3 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -68,6 +68,10 @@
 #define PAPR_SCM_PERF_STATS_EYECATCHER __stringify(SCMSTATS)
 #define PAPR_SCM_PERF_STATS_VERSION 0x1
 
+/* Use bitblt method to override specific bits in the '_bitmap_' */
+#define BITBLT_BITMAP(_bitmap_, _mask_, _override_)		\
+	(((_bitmap_) & ~(_mask_)) | ((_mask_) & (_override_)))
+
 /* Struct holding a single performance metric */
 struct papr_scm_perf_stat {
 	u8 stat_id[8];
@@ -120,6 +124,12 @@ struct papr_scm_priv {
 
 	/* length of the stat buffer as expected by phyp */
 	size_t stat_buffer_len;
+
+	/* The bits which needs to be overridden */
+	u64 health_bitmap_mask;
+
+	/* The overridden values for the bits having the masks set */
+	u64 health_bitmap_override;
 };
 
 static int papr_scm_pmem_flush(struct nd_region *nd_region,
@@ -347,19 +357,28 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p,
 static int __drc_pmem_query_health(struct papr_scm_priv *p)
 {
 	unsigned long ret[PLPAR_HCALL_BUFSIZE];
+	u64 bitmap = 0;
 	long rc;
 
 	/* issue the hcall */
 	rc = plpar_hcall(H_SCM_HEALTH, ret, p->drc_index);
-	if (rc != H_SUCCESS) {
+	if (rc == H_SUCCESS)
+		bitmap = ret[0] & ret[1];
+	else if (rc == H_FUNCTION)
+		dev_info_once(&p->pdev->dev,
+			      "Hcall H_SCM_HEALTH not implemented, assuming empty health bitmap");
+	else {
+
 		dev_err(&p->pdev->dev,
 			"Failed to query health information, Err:%ld\n", rc);
 		return -ENXIO;
 	}
 
 	p->lasthealth_jiffies = jiffies;
-	p->health_bitmap = ret[0] & ret[1];
-
+	/* Allow overriding specific health bits via bit blt. */
+	bitmap = BITBLT_BITMAP(bitmap, p->health_bitmap_mask,
+			       p->health_bitmap_override);
+	WRITE_ONCE(p->health_bitmap, bitmap);
 	dev_dbg(&p->pdev->dev,
 		"Queried dimm health info. Bitmap:0x%016lx Mask:0x%016lx\n",
 		ret[0], ret[1]);
@@ -669,6 +688,54 @@ static int papr_pdsm_health(struct papr_scm_priv *p,
 	return rc;
 }
 
+/* Inject a smart error Add the dirty-shutdown-counter value to the pdsm */
+static int papr_pdsm_smart_inject(struct papr_scm_priv *p,
+				  union nd_pdsm_payload *payload)
+{
+	int rc;
+	u32 supported_flags = 0;
+	u64 mask = 0, override = 0;
+
+	/* Check for individual smart error flags and update mask and override */
+	if (payload->smart_inject.flags & PDSM_SMART_INJECT_HEALTH_FATAL) {
+		supported_flags |= PDSM_SMART_INJECT_HEALTH_FATAL;
+		mask |= PAPR_PMEM_HEALTH_FATAL;
+		override |= payload->smart_inject.fatal_enable ?
+			PAPR_PMEM_HEALTH_FATAL : 0;
+	}
+
+	if (payload->smart_inject.flags & PDSM_SMART_INJECT_BAD_SHUTDOWN) {
+		supported_flags |= PDSM_SMART_INJECT_BAD_SHUTDOWN;
+		mask |= PAPR_PMEM_SHUTDOWN_DIRTY;
+		override |= payload->smart_inject.unsafe_shutdown_enable ?
+			PAPR_PMEM_SHUTDOWN_DIRTY : 0;
+	}
+
+	dev_dbg(&p->pdev->dev, "[Smart-inject] Mask=%#llx override=%#llx\n",
+		mask, override);
+
+	/* Prevent concurrent access to dimm health bitmap related members */
+	rc = mutex_lock_interruptible(&p->health_mutex);
+	if (rc)
+		return rc;
+
+	/* Bitblt mask/override to corrosponding health_bitmap couterparts */
+	p->health_bitmap_mask = BITBLT_BITMAP(p->health_bitmap_mask,
+					      mask, override);
+	p->health_bitmap_override = BITBLT_BITMAP(p->health_bitmap_override,
+						  mask, override);
+
+	/* Invalidate cached health bitmap */
+	p->lasthealth_jiffies = 0;
+
+	mutex_unlock(&p->health_mutex);
+
+	/* Return the supported flags back to userspace */
+	payload->smart_inject.flags = supported_flags;
+
+	return sizeof(struct nd_papr_pdsm_health);
+}
+
 /*
  * 'struct pdsm_cmd_desc'
  * Identifies supported PDSMs' expected length of in/out payloads
@@ -702,6 +769,12 @@ static const struct pdsm_cmd_desc __pdsm_cmd_descriptors[] = {
 		.size_out = sizeof(struct nd_papr_pdsm_health),
 		.service = papr_pdsm_health,
 	},
+
+	[PAPR_PDSM_SMART_INJECT] = {
+		.size_in = sizeof(struct nd_papr_pdsm_smart_inject),
+		.size_out = sizeof(struct nd_papr_pdsm_smart_inject),
+		.service = papr_pdsm_smart_inject,
+	},
 	/* Empty */
 	[PAPR_PDSM_MAX] = {
 		.size_in = 0,
@@ -838,6 +911,20 @@ static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc,
 	return 0;
 }
 
+static ssize_t health_bitmap_override_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct nvdimm *dimm = to_nvdimm(dev);
+	struct papr_scm_priv *p = nvdimm_provider_data(dimm);
+
+	return sprintf(buf, "mask=%#llx override=%#llx\n",
+		       READ_ONCE(p->health_bitmap_mask),
+		       READ_ONCE(p->health_bitmap_override));
+}
+
+static DEVICE_ATTR_ADMIN_RO(health_bitmap_override);
+
 static ssize_t perf_stats_show(struct device *dev,
 			       struct device_attribute *attr, char *buf)
 {
@@ -952,6 +1039,7 @@ static struct attribute *papr_nd_attributes[] = {
 	&dev_attr_flags.attr,
 	&dev_attr_perf_stats.attr,
 	&dev_attr_dirty_shutdown.attr,
+	&dev_attr_health_bitmap_override.attr,
 	NULL,
 };
 
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH 1/4] dt-bindings: pwm: Add Apple PWM controller
@ 2022-10-28 16:52  5%   ` Sasha Finkelstein
  0 siblings, 0 replies; 200+ results
From: Sasha Finkelstein @ 2022-10-28 16:52 UTC (permalink / raw)
  To: thierry.reding, robh+dt, krzysztof.kozlowski+dt
  Cc: marcan, sven, alyssa, asahi, linux-arm-kernel, linux-pwm,
	devicetree, linux-kernel, Sasha Finkelstein

Apple SoCs such as the M1 contain a PWM controller used
among other things to control the keyboard backlight.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
---
 .../devicetree/bindings/pwm/pwm-apple.yaml    | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-apple.yaml

diff --git a/Documentation/devicetree/bindings/pwm/pwm-apple.yaml b/Documentation/devicetree/bindings/pwm/pwm-apple.yaml
new file mode 100644
index 000000000000..39dc32e00a3f
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-apple.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/pwm-apple.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: |+
+  PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm: fpwm@235044000 {
+      compatible = "apple,s5l-fpwm";
+      reg = <0x2 0x35044000 0x0 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
-- 
2.37.3


^ permalink raw reply related	[relevance 5%]

* [PATCH v4] powerpc/papr_scm: Implement initial support for injecting smart errors
@ 2022-01-24 20:22  5% ` Vaibhav Jain
  0 siblings, 0 replies; 200+ results
From: Vaibhav Jain @ 2022-01-24 20:22 UTC (permalink / raw)
  To: nvdimm, linuxppc-dev
  Cc: Vaibhav Jain, Dan Williams, Aneesh Kumar K . V, Michael Ellerman,
	Shivaprasad G Bhat, Ira Weiny

Presently PAPR doesn't support injecting smart errors on an
NVDIMM. This makes testing the NVDIMM health reporting functionality
difficult as simulating NVDIMM health related events need a hacked up
qemu version.

To solve this problem this patch proposes simulating certain set of
NVDIMM health related events in papr_scm. Specifically 'fatal' health
state and 'dirty' shutdown state. These error can be injected via the
user-space 'ndctl-inject-smart(1)' command. With the proposed patch and
corresponding ndctl patches following command flow is expected:

$ sudo ndctl list -DH -d nmem0
...
      "health_state":"ok",
      "shutdown_state":"clean",
...
 # inject unsafe shutdown and fatal health error
$ sudo ndctl inject-smart nmem0 -Uf
...
      "health_state":"fatal",
      "shutdown_state":"dirty",
...
 # uninject all errors
$ sudo ndctl inject-smart nmem0 -N
...
      "health_state":"ok",
      "shutdown_state":"clean",
...

The patch adds a new member 'health_bitmap_inject_mask' inside struct
papr_scm_priv which is then bitwise ANDed to the health bitmap fetched from the
hypervisor. The value for 'health_bitmap_inject_mask' is accessible from sysfs
at nmemX/papr/health_bitmap_inject.

A new PDSM named 'SMART_INJECT' is proposed that accepts newly
introduced 'struct nd_papr_pdsm_smart_inject' as payload thats
exchanged between libndctl and papr_scm to indicate the requested
smart-error states.

When the processing the PDSM 'SMART_INJECT', papr_pdsm_smart_inject()
constructs a pair or 'inject_mask' and 'clear_mask' bitmaps from the payload
and bit-blt it to the 'health_bitmap_inject_mask'. This ensures the after being
fetched from the hypervisor, the health_bitmap reflects requested smart-error
states.

Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
---
Changelog:

Since v3:
* Renamed the sysfs entry from 'health_bitmap_override' to
'health_bitmap_inject'.
* Simplified the variable names and removed the 'health_bitmap_{mask,override}'
members. Instead replaced them with a single 'health_bitmap_inject_mask'
member. [Aneesh]
* Updated the sysfs documentations and commit description.
* Used READ/WRITE_ONCE macros at places where 'health_bitmap_inject_mask' may be
accessed concurrently.

Since v2:
* Rebased the patch to ppc-next
* Added documentation for newly introduced sysfs attribute 'health_bitmap_override'

Since v1:
* Updated the patch description.
* Removed dependency of a header movement patch.
* Removed '__packed' attribute for 'struct nd_papr_pdsm_smart_inject' [Aneesh]
---
 Documentation/ABI/testing/sysfs-bus-papr-pmem | 12 +++
 arch/powerpc/include/uapi/asm/papr_pdsm.h     | 18 ++++
 arch/powerpc/platforms/pseries/papr_scm.c     | 90 ++++++++++++++++++-
 3 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem
index 95254cec92bf..4ac0673901e7 100644
--- a/Documentation/ABI/testing/sysfs-bus-papr-pmem
+++ b/Documentation/ABI/testing/sysfs-bus-papr-pmem
@@ -61,3 +61,15 @@ Description:
 		* "CchRHCnt" : Cache Read Hit Count
 		* "CchWHCnt" : Cache Write Hit Count
 		* "FastWCnt" : Fast Write Count
+
+What:		/sys/bus/nd/devices/nmemX/papr/health_bitmap_inject
+Date:		Jan, 2022
+KernelVersion:	v5.17
+Contact:	linuxppc-dev <linuxppc-dev@lists.ozlabs.org>, nvdimm@lists.linux.dev,
+Description:
+		(RO) Reports the health bitmap inject bitmap that is applied to
+		bitmap received from PowerVM via the H_SCM_HEALTH. This is used
+		to forcibly set specific bits returned from Hcall. These is then
+		used to simulate various health or shutdown states for an nvdimm
+		and are set by user-space tools like ndctl by issuing a PAPR DSM.
+
diff --git a/arch/powerpc/include/uapi/asm/papr_pdsm.h b/arch/powerpc/include/uapi/asm/papr_pdsm.h
index 82488b1e7276..17439925045c 100644
--- a/arch/powerpc/include/uapi/asm/papr_pdsm.h
+++ b/arch/powerpc/include/uapi/asm/papr_pdsm.h
@@ -116,6 +116,22 @@ struct nd_papr_pdsm_health {
 	};
 };
 
+/* Flags for injecting specific smart errors */
+#define PDSM_SMART_INJECT_HEALTH_FATAL		(1 << 0)
+#define PDSM_SMART_INJECT_BAD_SHUTDOWN		(1 << 1)
+
+struct nd_papr_pdsm_smart_inject {
+	union {
+		struct {
+			/* One or more of PDSM_SMART_INJECT_ */
+			__u32 flags;
+			__u8 fatal_enable;
+			__u8 unsafe_shutdown_enable;
+		};
+		__u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
+	};
+};
+
 /*
  * Methods to be embedded in ND_CMD_CALL request. These are sent to the kernel
  * via 'nd_cmd_pkg.nd_command' member of the ioctl struct
@@ -123,12 +139,14 @@ struct nd_papr_pdsm_health {
 enum papr_pdsm {
 	PAPR_PDSM_MIN = 0x0,
 	PAPR_PDSM_HEALTH,
+	PAPR_PDSM_SMART_INJECT,
 	PAPR_PDSM_MAX,
 };
 
 /* Maximal union that can hold all possible payload types */
 union nd_pdsm_payload {
 	struct nd_papr_pdsm_health health;
+	struct nd_papr_pdsm_smart_inject smart_inject;
 	__u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
 } __packed;
 
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index f48e87ac89c9..20aafd387840 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -120,6 +120,10 @@ struct papr_scm_priv {
 
 	/* length of the stat buffer as expected by phyp */
 	size_t stat_buffer_len;
+
+	/* The bits which needs to be overridden */
+	u64 health_bitmap_inject_mask;
+
 };
 
 static int papr_scm_pmem_flush(struct nd_region *nd_region,
@@ -347,19 +351,29 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p,
 static int __drc_pmem_query_health(struct papr_scm_priv *p)
 {
 	unsigned long ret[PLPAR_HCALL_BUFSIZE];
+	u64 bitmap = 0;
 	long rc;
 
 	/* issue the hcall */
 	rc = plpar_hcall(H_SCM_HEALTH, ret, p->drc_index);
-	if (rc != H_SUCCESS) {
+	if (rc == H_SUCCESS)
+		bitmap = ret[0] & ret[1];
+	else if (rc == H_FUNCTION)
+		dev_info_once(&p->pdev->dev,
+			      "Hcall H_SCM_HEALTH not implemented, assuming empty health bitmap");
+	else {
+
 		dev_err(&p->pdev->dev,
 			"Failed to query health information, Err:%ld\n", rc);
 		return -ENXIO;
 	}
 
 	p->lasthealth_jiffies = jiffies;
-	p->health_bitmap = ret[0] & ret[1];
-
+	/* Allow injecting specific health bits via inject mask. */
+	if (p->health_bitmap_inject_mask)
+		bitmap = (bitmap & ~p->health_bitmap_inject_mask) |
+			p->health_bitmap_inject_mask;
+	WRITE_ONCE(p->health_bitmap, bitmap);
 	dev_dbg(&p->pdev->dev,
 		"Queried dimm health info. Bitmap:0x%016lx Mask:0x%016lx\n",
 		ret[0], ret[1]);
@@ -669,6 +683,56 @@ static int papr_pdsm_health(struct papr_scm_priv *p,
 	return rc;
 }
 
+/* Inject a smart error Add the dirty-shutdown-counter value to the pdsm */
+static int papr_pdsm_smart_inject(struct papr_scm_priv *p,
+				  union nd_pdsm_payload *payload)
+{
+	int rc;
+	u32 supported_flags = 0;
+	u64 inject_mask = 0, clear_mask = 0;
+	u64 mask;
+
+	/* Check for individual smart error flags and update inject/clear masks */
+	if (payload->smart_inject.flags & PDSM_SMART_INJECT_HEALTH_FATAL) {
+		supported_flags |= PDSM_SMART_INJECT_HEALTH_FATAL;
+		if (payload->smart_inject.fatal_enable)
+			inject_mask |= PAPR_PMEM_HEALTH_FATAL;
+		else
+			clear_mask |= PAPR_PMEM_HEALTH_FATAL;
+	}
+
+	if (payload->smart_inject.flags & PDSM_SMART_INJECT_BAD_SHUTDOWN) {
+		supported_flags |= PDSM_SMART_INJECT_BAD_SHUTDOWN;
+		if (payload->smart_inject.unsafe_shutdown_enable)
+			inject_mask |= PAPR_PMEM_SHUTDOWN_DIRTY;
+		else
+			clear_mask |= PAPR_PMEM_SHUTDOWN_DIRTY;
+	}
+
+	dev_dbg(&p->pdev->dev, "[Smart-inject] inject_mask=%#llx clear_mask=%#llx\n",
+		inject_mask, clear_mask);
+
+	/* Prevent concurrent access to dimm health bitmap related members */
+	rc = mutex_lock_interruptible(&p->health_mutex);
+	if (rc)
+		return rc;
+
+	/* Use inject/clear masks to set health_bitmap_inject_mask */
+	mask = READ_ONCE(p->health_bitmap_inject_mask);
+	mask = (mask & ~clear_mask) | inject_mask;
+	WRITE_ONCE(p->health_bitmap_inject_mask, mask);
+
+	/* Invalidate cached health bitmap */
+	p->lasthealth_jiffies = 0;
+
+	mutex_unlock(&p->health_mutex);
+
+	/* Return the supported flags back to userspace */
+	payload->smart_inject.flags = supported_flags;
+
+	return sizeof(struct nd_papr_pdsm_health);
+}
+
 /*
  * 'struct pdsm_cmd_desc'
  * Identifies supported PDSMs' expected length of in/out payloads
@@ -702,6 +766,12 @@ static const struct pdsm_cmd_desc __pdsm_cmd_descriptors[] = {
 		.size_out = sizeof(struct nd_papr_pdsm_health),
 		.service = papr_pdsm_health,
 	},
+
+	[PAPR_PDSM_SMART_INJECT] = {
+		.size_in = sizeof(struct nd_papr_pdsm_smart_inject),
+		.size_out = sizeof(struct nd_papr_pdsm_smart_inject),
+		.service = papr_pdsm_smart_inject,
+	},
 	/* Empty */
 	[PAPR_PDSM_MAX] = {
 		.size_in = 0,
@@ -838,6 +908,19 @@ static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc,
 	return 0;
 }
 
+static ssize_t health_bitmap_inject_show(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct nvdimm *dimm = to_nvdimm(dev);
+	struct papr_scm_priv *p = nvdimm_provider_data(dimm);
+
+	return sprintf(buf, "%#llx\n",
+		       READ_ONCE(p->health_bitmap_inject_mask));
+}
+
+static DEVICE_ATTR_ADMIN_RO(health_bitmap_inject);
+
 static ssize_t perf_stats_show(struct device *dev,
 			       struct device_attribute *attr, char *buf)
 {
@@ -952,6 +1035,7 @@ static struct attribute *papr_nd_attributes[] = {
 	&dev_attr_flags.attr,
 	&dev_attr_perf_stats.attr,
 	&dev_attr_dirty_shutdown.attr,
+	&dev_attr_health_bitmap_inject.attr,
 	NULL,
 };
 
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v4] powerpc/papr_scm: Implement initial support for injecting smart errors
@ 2022-01-24 20:22  5% ` Vaibhav Jain
  0 siblings, 0 replies; 200+ results
From: Vaibhav Jain @ 2022-01-24 20:22 UTC (permalink / raw)
  To: nvdimm, linuxppc-dev
  Cc: Shivaprasad G Bhat, Aneesh Kumar K . V, Vaibhav Jain,
	Dan Williams, Ira Weiny

Presently PAPR doesn't support injecting smart errors on an
NVDIMM. This makes testing the NVDIMM health reporting functionality
difficult as simulating NVDIMM health related events need a hacked up
qemu version.

To solve this problem this patch proposes simulating certain set of
NVDIMM health related events in papr_scm. Specifically 'fatal' health
state and 'dirty' shutdown state. These error can be injected via the
user-space 'ndctl-inject-smart(1)' command. With the proposed patch and
corresponding ndctl patches following command flow is expected:

$ sudo ndctl list -DH -d nmem0
...
      "health_state":"ok",
      "shutdown_state":"clean",
...
 # inject unsafe shutdown and fatal health error
$ sudo ndctl inject-smart nmem0 -Uf
...
      "health_state":"fatal",
      "shutdown_state":"dirty",
...
 # uninject all errors
$ sudo ndctl inject-smart nmem0 -N
...
      "health_state":"ok",
      "shutdown_state":"clean",
...

The patch adds a new member 'health_bitmap_inject_mask' inside struct
papr_scm_priv which is then bitwise ANDed to the health bitmap fetched from the
hypervisor. The value for 'health_bitmap_inject_mask' is accessible from sysfs
at nmemX/papr/health_bitmap_inject.

A new PDSM named 'SMART_INJECT' is proposed that accepts newly
introduced 'struct nd_papr_pdsm_smart_inject' as payload thats
exchanged between libndctl and papr_scm to indicate the requested
smart-error states.

When the processing the PDSM 'SMART_INJECT', papr_pdsm_smart_inject()
constructs a pair or 'inject_mask' and 'clear_mask' bitmaps from the payload
and bit-blt it to the 'health_bitmap_inject_mask'. This ensures the after being
fetched from the hypervisor, the health_bitmap reflects requested smart-error
states.

Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
---
Changelog:

Since v3:
* Renamed the sysfs entry from 'health_bitmap_override' to
'health_bitmap_inject'.
* Simplified the variable names and removed the 'health_bitmap_{mask,override}'
members. Instead replaced them with a single 'health_bitmap_inject_mask'
member. [Aneesh]
* Updated the sysfs documentations and commit description.
* Used READ/WRITE_ONCE macros at places where 'health_bitmap_inject_mask' may be
accessed concurrently.

Since v2:
* Rebased the patch to ppc-next
* Added documentation for newly introduced sysfs attribute 'health_bitmap_override'

Since v1:
* Updated the patch description.
* Removed dependency of a header movement patch.
* Removed '__packed' attribute for 'struct nd_papr_pdsm_smart_inject' [Aneesh]
---
 Documentation/ABI/testing/sysfs-bus-papr-pmem | 12 +++
 arch/powerpc/include/uapi/asm/papr_pdsm.h     | 18 ++++
 arch/powerpc/platforms/pseries/papr_scm.c     | 90 ++++++++++++++++++-
 3 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem
index 95254cec92bf..4ac0673901e7 100644
--- a/Documentation/ABI/testing/sysfs-bus-papr-pmem
+++ b/Documentation/ABI/testing/sysfs-bus-papr-pmem
@@ -61,3 +61,15 @@ Description:
 		* "CchRHCnt" : Cache Read Hit Count
 		* "CchWHCnt" : Cache Write Hit Count
 		* "FastWCnt" : Fast Write Count
+
+What:		/sys/bus/nd/devices/nmemX/papr/health_bitmap_inject
+Date:		Jan, 2022
+KernelVersion:	v5.17
+Contact:	linuxppc-dev <linuxppc-dev@lists.ozlabs.org>, nvdimm@lists.linux.dev,
+Description:
+		(RO) Reports the health bitmap inject bitmap that is applied to
+		bitmap received from PowerVM via the H_SCM_HEALTH. This is used
+		to forcibly set specific bits returned from Hcall. These is then
+		used to simulate various health or shutdown states for an nvdimm
+		and are set by user-space tools like ndctl by issuing a PAPR DSM.
+
diff --git a/arch/powerpc/include/uapi/asm/papr_pdsm.h b/arch/powerpc/include/uapi/asm/papr_pdsm.h
index 82488b1e7276..17439925045c 100644
--- a/arch/powerpc/include/uapi/asm/papr_pdsm.h
+++ b/arch/powerpc/include/uapi/asm/papr_pdsm.h
@@ -116,6 +116,22 @@ struct nd_papr_pdsm_health {
 	};
 };
 
+/* Flags for injecting specific smart errors */
+#define PDSM_SMART_INJECT_HEALTH_FATAL		(1 << 0)
+#define PDSM_SMART_INJECT_BAD_SHUTDOWN		(1 << 1)
+
+struct nd_papr_pdsm_smart_inject {
+	union {
+		struct {
+			/* One or more of PDSM_SMART_INJECT_ */
+			__u32 flags;
+			__u8 fatal_enable;
+			__u8 unsafe_shutdown_enable;
+		};
+		__u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
+	};
+};
+
 /*
  * Methods to be embedded in ND_CMD_CALL request. These are sent to the kernel
  * via 'nd_cmd_pkg.nd_command' member of the ioctl struct
@@ -123,12 +139,14 @@ struct nd_papr_pdsm_health {
 enum papr_pdsm {
 	PAPR_PDSM_MIN = 0x0,
 	PAPR_PDSM_HEALTH,
+	PAPR_PDSM_SMART_INJECT,
 	PAPR_PDSM_MAX,
 };
 
 /* Maximal union that can hold all possible payload types */
 union nd_pdsm_payload {
 	struct nd_papr_pdsm_health health;
+	struct nd_papr_pdsm_smart_inject smart_inject;
 	__u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
 } __packed;
 
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index f48e87ac89c9..20aafd387840 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -120,6 +120,10 @@ struct papr_scm_priv {
 
 	/* length of the stat buffer as expected by phyp */
 	size_t stat_buffer_len;
+
+	/* The bits which needs to be overridden */
+	u64 health_bitmap_inject_mask;
+
 };
 
 static int papr_scm_pmem_flush(struct nd_region *nd_region,
@@ -347,19 +351,29 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p,
 static int __drc_pmem_query_health(struct papr_scm_priv *p)
 {
 	unsigned long ret[PLPAR_HCALL_BUFSIZE];
+	u64 bitmap = 0;
 	long rc;
 
 	/* issue the hcall */
 	rc = plpar_hcall(H_SCM_HEALTH, ret, p->drc_index);
-	if (rc != H_SUCCESS) {
+	if (rc == H_SUCCESS)
+		bitmap = ret[0] & ret[1];
+	else if (rc == H_FUNCTION)
+		dev_info_once(&p->pdev->dev,
+			      "Hcall H_SCM_HEALTH not implemented, assuming empty health bitmap");
+	else {
+
 		dev_err(&p->pdev->dev,
 			"Failed to query health information, Err:%ld\n", rc);
 		return -ENXIO;
 	}
 
 	p->lasthealth_jiffies = jiffies;
-	p->health_bitmap = ret[0] & ret[1];
-
+	/* Allow injecting specific health bits via inject mask. */
+	if (p->health_bitmap_inject_mask)
+		bitmap = (bitmap & ~p->health_bitmap_inject_mask) |
+			p->health_bitmap_inject_mask;
+	WRITE_ONCE(p->health_bitmap, bitmap);
 	dev_dbg(&p->pdev->dev,
 		"Queried dimm health info. Bitmap:0x%016lx Mask:0x%016lx\n",
 		ret[0], ret[1]);
@@ -669,6 +683,56 @@ static int papr_pdsm_health(struct papr_scm_priv *p,
 	return rc;
 }
 
+/* Inject a smart error Add the dirty-shutdown-counter value to the pdsm */
+static int papr_pdsm_smart_inject(struct papr_scm_priv *p,
+				  union nd_pdsm_payload *payload)
+{
+	int rc;
+	u32 supported_flags = 0;
+	u64 inject_mask = 0, clear_mask = 0;
+	u64 mask;
+
+	/* Check for individual smart error flags and update inject/clear masks */
+	if (payload->smart_inject.flags & PDSM_SMART_INJECT_HEALTH_FATAL) {
+		supported_flags |= PDSM_SMART_INJECT_HEALTH_FATAL;
+		if (payload->smart_inject.fatal_enable)
+			inject_mask |= PAPR_PMEM_HEALTH_FATAL;
+		else
+			clear_mask |= PAPR_PMEM_HEALTH_FATAL;
+	}
+
+	if (payload->smart_inject.flags & PDSM_SMART_INJECT_BAD_SHUTDOWN) {
+		supported_flags |= PDSM_SMART_INJECT_BAD_SHUTDOWN;
+		if (payload->smart_inject.unsafe_shutdown_enable)
+			inject_mask |= PAPR_PMEM_SHUTDOWN_DIRTY;
+		else
+			clear_mask |= PAPR_PMEM_SHUTDOWN_DIRTY;
+	}
+
+	dev_dbg(&p->pdev->dev, "[Smart-inject] inject_mask=%#llx clear_mask=%#llx\n",
+		inject_mask, clear_mask);
+
+	/* Prevent concurrent access to dimm health bitmap related members */
+	rc = mutex_lock_interruptible(&p->health_mutex);
+	if (rc)
+		return rc;
+
+	/* Use inject/clear masks to set health_bitmap_inject_mask */
+	mask = READ_ONCE(p->health_bitmap_inject_mask);
+	mask = (mask & ~clear_mask) | inject_mask;
+	WRITE_ONCE(p->health_bitmap_inject_mask, mask);
+
+	/* Invalidate cached health bitmap */
+	p->lasthealth_jiffies = 0;
+
+	mutex_unlock(&p->health_mutex);
+
+	/* Return the supported flags back to userspace */
+	payload->smart_inject.flags = supported_flags;
+
+	return sizeof(struct nd_papr_pdsm_health);
+}
+
 /*
  * 'struct pdsm_cmd_desc'
  * Identifies supported PDSMs' expected length of in/out payloads
@@ -702,6 +766,12 @@ static const struct pdsm_cmd_desc __pdsm_cmd_descriptors[] = {
 		.size_out = sizeof(struct nd_papr_pdsm_health),
 		.service = papr_pdsm_health,
 	},
+
+	[PAPR_PDSM_SMART_INJECT] = {
+		.size_in = sizeof(struct nd_papr_pdsm_smart_inject),
+		.size_out = sizeof(struct nd_papr_pdsm_smart_inject),
+		.service = papr_pdsm_smart_inject,
+	},
 	/* Empty */
 	[PAPR_PDSM_MAX] = {
 		.size_in = 0,
@@ -838,6 +908,19 @@ static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc,
 	return 0;
 }
 
+static ssize_t health_bitmap_inject_show(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct nvdimm *dimm = to_nvdimm(dev);
+	struct papr_scm_priv *p = nvdimm_provider_data(dimm);
+
+	return sprintf(buf, "%#llx\n",
+		       READ_ONCE(p->health_bitmap_inject_mask));
+}
+
+static DEVICE_ATTR_ADMIN_RO(health_bitmap_inject);
+
 static ssize_t perf_stats_show(struct device *dev,
 			       struct device_attribute *attr, char *buf)
 {
@@ -952,6 +1035,7 @@ static struct attribute *papr_nd_attributes[] = {
 	&dev_attr_flags.attr,
 	&dev_attr_perf_stats.attr,
 	&dev_attr_dirty_shutdown.attr,
+	&dev_attr_health_bitmap_inject.attr,
 	NULL,
 };
 
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v3 1/3] bus: mhi: host: Add sysfs entry to force device to enter EDL
  @ 2024-04-15  8:49  5% ` Qiang Yu
  0 siblings, 0 replies; 200+ results
From: Qiang Yu @ 2024-04-15  8:49 UTC (permalink / raw)
  To: mani, quic_jhugo
  Cc: mhi, linux-arm-msm, linux-kernel, quic_cang, quic_mrana, Qiang Yu

Add sysfs entry to allow users of MHI bus force device to enter EDL.
Considering that the way to enter EDL mode varies from device to device and
some devices even do not support EDL. Hence, add a callback edl_trigger in
mhi controller as part of the sysfs entry to be invoked and MHI core will
only create EDL sysfs entry for mhi controller that provides edl_trigger
callback. All of the process a specific device required to enter EDL mode
can be placed in this callback.

Signed-off-by: Qiang Yu <quic_qianyu@quicinc.com>
---
 Documentation/ABI/stable/sysfs-bus-mhi | 11 +++++++++++
 drivers/bus/mhi/host/init.c            | 35 ++++++++++++++++++++++++++++++++++
 include/linux/mhi.h                    |  2 ++
 3 files changed, 48 insertions(+)

diff --git a/Documentation/ABI/stable/sysfs-bus-mhi b/Documentation/ABI/stable/sysfs-bus-mhi
index 1a47f9e..d0bf9ae 100644
--- a/Documentation/ABI/stable/sysfs-bus-mhi
+++ b/Documentation/ABI/stable/sysfs-bus-mhi
@@ -29,3 +29,14 @@ Description:	Initiates a SoC reset on the MHI controller.  A SoC reset is
                 This can be useful as a method of recovery if the device is
                 non-responsive, or as a means of loading new firmware as a
                 system administration task.
+
+What:           /sys/bus/mhi/devices/.../force_edl
+Date:           April 2024
+KernelVersion:  6.9
+Contact:        mhi@lists.linux.dev
+Description:    Force devices to enter EDL (emergency download) mode. Only MHI
+                controller that supports EDL mode and provides a mechanism for
+                manually triggering EDL contains this file. Once in EDL mode,
+                the flash programmer image can be downloaded to the device to
+                enter the flash programmer execution environment. This can be
+                useful if user wants to update firmware.
diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c
index 44f9349..333ac94 100644
--- a/drivers/bus/mhi/host/init.c
+++ b/drivers/bus/mhi/host/init.c
@@ -127,6 +127,32 @@ static ssize_t soc_reset_store(struct device *dev,
 }
 static DEVICE_ATTR_WO(soc_reset);
 
+static ssize_t force_edl_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct mhi_device *mhi_dev = to_mhi_device(dev);
+	struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+	unsigned long val;
+	int ret;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret < 0) {
+		dev_err(dev, "Could not parse string: %d\n", ret);
+		return ret;
+	}
+
+	if (!val)
+		return count;
+
+	ret = mhi_cntrl->edl_trigger(mhi_cntrl);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static DEVICE_ATTR_WO(force_edl);
+
 static struct attribute *mhi_dev_attrs[] = {
 	&dev_attr_serial_number.attr,
 	&dev_attr_oem_pk_hash.attr,
@@ -1018,6 +1044,12 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
 	if (ret)
 		goto err_release_dev;
 
+	if (mhi_cntrl->edl_trigger) {
+		ret = sysfs_create_file(&mhi_dev->dev.kobj, &dev_attr_force_edl.attr);
+		if (ret)
+			goto err_release_dev;
+	}
+
 	mhi_cntrl->mhi_dev = mhi_dev;
 
 	mhi_create_debugfs(mhi_cntrl);
@@ -1051,6 +1083,9 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl)
 	mhi_deinit_free_irq(mhi_cntrl);
 	mhi_destroy_debugfs(mhi_cntrl);
 
+	if (mhi_cntrl->edl_trigger)
+		sysfs_remove_file(&mhi_dev->dev.kobj, &dev_attr_force_edl.attr);
+
 	destroy_workqueue(mhi_cntrl->hiprio_wq);
 	kfree(mhi_cntrl->mhi_cmd);
 	kfree(mhi_cntrl->mhi_event);
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index cde01e1..8280545 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -353,6 +353,7 @@ struct mhi_controller_config {
  * @read_reg: Read a MHI register via the physical link (required)
  * @write_reg: Write a MHI register via the physical link (required)
  * @reset: Controller specific reset function (optional)
+ * @edl_trigger: CB function to enter EDL mode (optional)
  * @buffer_len: Bounce buffer length
  * @index: Index of the MHI controller instance
  * @bounce_buf: Use of bounce buffer
@@ -435,6 +436,7 @@ struct mhi_controller {
 	void (*write_reg)(struct mhi_controller *mhi_cntrl, void __iomem *addr,
 			  u32 val);
 	void (*reset)(struct mhi_controller *mhi_cntrl);
+	int (*edl_trigger)(struct mhi_controller *mhi_cntrl);
 
 	size_t buffer_len;
 	int index;
-- 
2.7.4


^ permalink raw reply related	[relevance 5%]

* [xenomai-images][PATCH v2 4/7] xenomai-4: Add evl userspace
  @ 2023-12-21 16:37  5% ` Clara Kowalsky
  0 siblings, 0 replies; 200+ results
From: Clara Kowalsky @ 2023-12-21 16:37 UTC (permalink / raw)
  To: xenomai, rpm; +Cc: jan.kiszka, Clara Kowalsky

The libevl recipe allows building the evl userspace.

Signed-off-by: Clara Kowalsky <clara.kowalsky@siemens.com>
---
 opt-libevl-master.yml                         | 19 ++++++++
 opt-libevl-next.yml                           | 20 ++++++++
 opt-libevl-r46.yml                            | 19 ++++++++
 opt-libevl-stable.yml                         | 19 ++++++++
 recipes-core/images/demo-image.bb             |  2 +
 recipes-xenomai/libevl/files/debian/compat    |  1 +
 .../libevl/files/debian/control.tmpl          | 10 ++++
 recipes-xenomai/libevl/files/debian/rules     |  7 +++
 recipes-xenomai/libevl/libevl_master.bb       | 47 +++++++++++++++++++
 recipes-xenomai/libevl/libevl_next.bb         |  1 +
 recipes-xenomai/libevl/libevl_r46.bb          | 46 ++++++++++++++++++
 recipes-xenomai/libevl/libevl_r47.bb          |  1 +
 12 files changed, 192 insertions(+)
 create mode 100644 opt-libevl-master.yml
 create mode 100644 opt-libevl-next.yml
 create mode 100644 opt-libevl-r46.yml
 create mode 100644 opt-libevl-stable.yml
 create mode 100644 recipes-xenomai/libevl/files/debian/compat
 create mode 100644 recipes-xenomai/libevl/files/debian/control.tmpl
 create mode 100755 recipes-xenomai/libevl/files/debian/rules
 create mode 100644 recipes-xenomai/libevl/libevl_master.bb
 create mode 120000 recipes-xenomai/libevl/libevl_next.bb
 create mode 100644 recipes-xenomai/libevl/libevl_r46.bb
 create mode 120000 recipes-xenomai/libevl/libevl_r47.bb

diff --git a/opt-libevl-master.yml b/opt-libevl-master.yml
new file mode 100644
index 0000000..a3fb14f
--- /dev/null
+++ b/opt-libevl-master.yml
@@ -0,0 +1,19 @@
+#
+# Xenomai Real-Time System
+#
+# Copyright (c) Siemens AG, 2023
+#
+# Authors:
+#  Clara Kowalsky <clara.kowalsky@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+#
+
+header:
+  version: 10
+
+local_conf_header:
+  libevl-version: |
+    PREFERRED_VERSION_libevl = "master"
+  xenomai-4_override: |
+    OVERRIDES .= ":xenomai4"
diff --git a/opt-libevl-next.yml b/opt-libevl-next.yml
new file mode 100644
index 0000000..5e22d43
--- /dev/null
+++ b/opt-libevl-next.yml
@@ -0,0 +1,20 @@
+#
+# Xenomai Real-Time System
+#
+# Copyright (c) Siemens AG, 2023
+#
+# Authors:
+#  Clara Kowalsky <clara.kowalsky@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+#
+
+header:
+  version: 10
+
+local_conf_header:
+  libevl-version: |
+    PREFERRED_VERSION_libevl = "next"
+  xenomai-4_override: |
+    OVERRIDES .= ":xenomai4"
+
diff --git a/opt-libevl-r46.yml b/opt-libevl-r46.yml
new file mode 100644
index 0000000..53d15f0
--- /dev/null
+++ b/opt-libevl-r46.yml
@@ -0,0 +1,19 @@
+#
+# Xenomai Real-Time System
+#
+# Copyright (c) Siemens AG, 2023
+#
+# Authors:
+#  Clara Kowalsky <clara.kowalsky@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+#
+
+header:
+  version: 10
+
+local_conf_header:
+  libevl-version: |
+    PREFERRED_VERSION_libevl = "r46"
+  xenomai-4_override: |
+    OVERRIDES .= ":xenomai4"
diff --git a/opt-libevl-stable.yml b/opt-libevl-stable.yml
new file mode 100644
index 0000000..d9ce4a1
--- /dev/null
+++ b/opt-libevl-stable.yml
@@ -0,0 +1,19 @@
+#
+# Xenomai Real-Time System
+#
+# Copyright (c) Siemens AG, 2023
+#
+# Authors:
+#  Clara Kowalsky <clara.kowalsky@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+#
+
+header:
+  version: 10
+
+local_conf_header:
+  libevl-version: |
+    PREFERRED_VERSION_libevl = "r47"
+  xenomai-4_override: |
+    OVERRIDES .= ":xenomai4"
diff --git a/recipes-core/images/demo-image.bb b/recipes-core/images/demo-image.bb
index db7e2c7..e19a038 100644
--- a/recipes-core/images/demo-image.bb
+++ b/recipes-core/images/demo-image.bb
@@ -44,4 +44,6 @@ IMAGE_PREINSTALL += " \
 IMAGE_INSTALL:append:xenomai3 = " xenomai-runtime xenomai-runtime-dbgsym"
 IMAGE_INSTALL:append:xenomai3 = " ${@get_testsuite_package_names(d)}"
 IMAGE_INSTALL:append:xenomai3 = " libxenomai1-dbgsym"
+IMAGE_INSTALL:append:xenomai4 = " libevl"
+
 IMAGE_INSTALL += "customizations sshd-regen-keys expand-on-first-boot"
diff --git a/recipes-xenomai/libevl/files/debian/compat b/recipes-xenomai/libevl/files/debian/compat
new file mode 100644
index 0000000..f599e28
--- /dev/null
+++ b/recipes-xenomai/libevl/files/debian/compat
@@ -0,0 +1 @@
+10
diff --git a/recipes-xenomai/libevl/files/debian/control.tmpl b/recipes-xenomai/libevl/files/debian/control.tmpl
new file mode 100644
index 0000000..9880ee9
--- /dev/null
+++ b/recipes-xenomai/libevl/files/debian/control.tmpl
@@ -0,0 +1,10 @@
+Source: ${PN}
+Section: misc
+Priority: optional
+Standards-Version: 3.9.6
+Maintainer: Xenomai project <xenomai@lists.linux.dev>
+Build-Depends: ${DEBIAN_BUILD_DEPENDS}
+
+Package: libevl
+Architecture: ${DISTRO_ARCH}
+Description: ${DESCRIPTION}
diff --git a/recipes-xenomai/libevl/files/debian/rules b/recipes-xenomai/libevl/files/debian/rules
new file mode 100755
index 0000000..9d9670e
--- /dev/null
+++ b/recipes-xenomai/libevl/files/debian/rules
@@ -0,0 +1,7 @@
+#!/usr/bin/make -f
+
+override_dh_fixperms:
+	dh_fixperms
+
+%:
+	dh $@ --buildsystem=meson
diff --git a/recipes-xenomai/libevl/libevl_master.bb b/recipes-xenomai/libevl/libevl_master.bb
new file mode 100644
index 0000000..d5ad572
--- /dev/null
+++ b/recipes-xenomai/libevl/libevl_master.bb
@@ -0,0 +1,47 @@
+#
+# Xenomai Real-Time System
+#
+# Copyright (c) Siemens AG, 2018-2023
+#
+# Authors:
+#  Clara Kowalsky <clara.kowalsky@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+#
+
+inherit dpkg
+
+CHANGELOG_V = "9999-${PV}"
+SRCREV = "${AUTOREV}"
+
+SRC_URI = " \
+        git://source.denx.de/Xenomai/xenomai4/libevl.git;protocol=https;branch=${PV} \
+        file://debian \
+        "
+
+DEPENDS="linux-xenomai-4"
+
+S = "${WORKDIR}/git"
+
+def get_commit(d):
+    try:
+        return bb.fetch2.get_srcrev(d).strip('AUTOINC+')
+    except bb.fetch2.FetchError:
+        return ""
+
+COMMIT="${@get_commit(d)}"
+
+DESCRIPTION ?= "install libevl libraries and tools"
+DEBIAN_BUILD_DEPENDS ?= "debhelper (>= 10), meson, linux-libc-dev"
+
+TEMPLATE_FILES = "debian/control.tmpl"
+TEMPLATE_VARS += "DEBIAN_BUILD_DEPENDS"
+
+do_prepare_build[cleandirs] += "${S}/debian"
+do_prepare_build() {
+    cp -r ${WORKDIR}/debian ${S}
+    deb_add_changelog
+
+    bbplain $(printf "libevl-%s: Building revision %.20s\n" \
+                    ${PV} ${COMMIT})
+}
diff --git a/recipes-xenomai/libevl/libevl_next.bb b/recipes-xenomai/libevl/libevl_next.bb
new file mode 120000
index 0000000..85ab518
--- /dev/null
+++ b/recipes-xenomai/libevl/libevl_next.bb
@@ -0,0 +1 @@
+libevl_master.bb
\ No newline at end of file
diff --git a/recipes-xenomai/libevl/libevl_r46.bb b/recipes-xenomai/libevl/libevl_r46.bb
new file mode 100644
index 0000000..a8bc597
--- /dev/null
+++ b/recipes-xenomai/libevl/libevl_r46.bb
@@ -0,0 +1,46 @@
+#
+# Xenomai Real-Time System
+#
+# Copyright (c) Siemens AG, 2018-2023
+#
+# Authors:
+#  Clara Kowalsky <clara.kowalsky@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+#
+
+inherit dpkg
+
+CHANGELOG_V = "9999-${PV}"
+
+SRC_URI = " \
+        git://source.denx.de/Xenomai/xenomai4/libevl.git;protocol=https;branch=master;tag=${PV} \
+        file://debian \
+        "
+
+DEPENDS="linux-xenomai-4"
+
+S = "${WORKDIR}/git"
+
+def get_commit(d):
+    try:
+        return bb.fetch2.get_srcrev(d).strip('AUTOINC+')
+    except bb.fetch2.FetchError:
+        return ""
+
+COMMIT="${@get_commit(d)}"
+
+DESCRIPTION ?= "install libevl libraries and tools"
+DEBIAN_BUILD_DEPENDS ?= "debhelper (>= 10), meson, linux-libc-dev"
+
+TEMPLATE_FILES = "debian/control.tmpl"
+TEMPLATE_VARS += "DEBIAN_BUILD_DEPENDS"
+
+do_prepare_build[cleandirs] += "${S}/debian"
+do_prepare_build() {
+    cp -r ${WORKDIR}/debian ${S}
+    deb_add_changelog
+
+    bbplain $(printf "libevl-%s: Building revision %.20s\n" \
+                    ${PV} ${COMMIT})
+}
diff --git a/recipes-xenomai/libevl/libevl_r47.bb b/recipes-xenomai/libevl/libevl_r47.bb
new file mode 120000
index 0000000..54ca27a
--- /dev/null
+++ b/recipes-xenomai/libevl/libevl_r47.bb
@@ -0,0 +1 @@
+libevl_r46.bb
\ No newline at end of file
-- 
2.39.2


^ permalink raw reply related	[relevance 5%]

* Re: Linux 5.18.11
  @ 2022-07-12 14:59  5% ` Greg Kroah-Hartman
  0 siblings, 0 replies; 200+ results
From: Greg Kroah-Hartman @ 2022-07-12 14:59 UTC (permalink / raw)
  To: linux-kernel, akpm, torvalds, stable; +Cc: lwn, jslaby, Greg Kroah-Hartman

diff --git a/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
index b6e1ebfaf366..bb3cbc30d912 100644
--- a/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
+++ b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
@@ -64,7 +64,7 @@ if:
 then:
   properties:
     clocks:
-      maxItems: 2
+      minItems: 2
 
   required:
     - clock-names
diff --git a/MAINTAINERS b/MAINTAINERS
index 8e6622ed6de6..2b70e2d21405 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -426,7 +426,6 @@ F:	drivers/acpi/*thermal*
 ACPI VIOT DRIVER
 M:	Jean-Philippe Brucker <jean-philippe@linaro.org>
 L:	linux-acpi@vger.kernel.org
-L:	iommu@lists.linux-foundation.org
 L:	iommu@lists.linux.dev
 S:	Maintained
 F:	drivers/acpi/viot.c
@@ -960,7 +959,6 @@ F:	drivers/video/fbdev/geode/
 AMD IOMMU (AMD-VI)
 M:	Joerg Roedel <joro@8bytes.org>
 R:	Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
-L:	iommu@lists.linux-foundation.org
 L:	iommu@lists.linux.dev
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
@@ -5899,7 +5897,6 @@ DMA MAPPING HELPERS
 M:	Christoph Hellwig <hch@lst.de>
 M:	Marek Szyprowski <m.szyprowski@samsung.com>
 R:	Robin Murphy <robin.murphy@arm.com>
-L:	iommu@lists.linux-foundation.org
 L:	iommu@lists.linux.dev
 S:	Supported
 W:	http://git.infradead.org/users/hch/dma-mapping.git
@@ -5912,7 +5909,6 @@ F:	kernel/dma/
 
 DMA MAPPING BENCHMARK
 M:	Xiang Chen <chenxiang66@hisilicon.com>
-L:	iommu@lists.linux-foundation.org
 L:	iommu@lists.linux.dev
 F:	kernel/dma/map_benchmark.c
 F:	tools/testing/selftests/dma/
@@ -7479,7 +7475,6 @@ F:	drivers/gpu/drm/exynos/exynos_dp*
 
 EXYNOS SYSMMU (IOMMU) driver
 M:	Marek Szyprowski <m.szyprowski@samsung.com>
-L:	iommu@lists.linux-foundation.org
 L:	iommu@lists.linux.dev
 S:	Maintained
 F:	drivers/iommu/exynos-iommu.c
@@ -9879,7 +9874,6 @@ F:	drivers/hid/intel-ish-hid/
 INTEL IOMMU (VT-d)
 M:	David Woodhouse <dwmw2@infradead.org>
 M:	Lu Baolu <baolu.lu@linux.intel.com>
-L:	iommu@lists.linux-foundation.org
 L:	iommu@lists.linux.dev
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
@@ -10258,7 +10252,6 @@ F:	include/linux/iomap.h
 IOMMU DRIVERS
 M:	Joerg Roedel <joro@8bytes.org>
 M:	Will Deacon <will@kernel.org>
-L:	iommu@lists.linux-foundation.org
 L:	iommu@lists.linux.dev
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
@@ -12375,7 +12368,6 @@ F:	drivers/i2c/busses/i2c-mt65xx.c
 
 MEDIATEK IOMMU DRIVER
 M:	Yong Wu <yong.wu@mediatek.com>
-L:	iommu@lists.linux-foundation.org
 L:	iommu@lists.linux.dev
 L:	linux-mediatek@lists.infradead.org (moderated for non-subscribers)
 S:	Supported
@@ -16361,7 +16353,6 @@ F:	drivers/i2c/busses/i2c-qcom-cci.c
 
 QUALCOMM IOMMU
 M:	Rob Clark <robdclark@gmail.com>
-L:	iommu@lists.linux-foundation.org
 L:	iommu@lists.linux.dev
 L:	linux-arm-msm@vger.kernel.org
 S:	Maintained
@@ -18947,7 +18938,6 @@ F:	arch/x86/boot/video*
 
 SWIOTLB SUBSYSTEM
 M:	Christoph Hellwig <hch@infradead.org>
-L:	iommu@lists.linux-foundation.org
 L:	iommu@lists.linux.dev
 S:	Supported
 W:	http://git.infradead.org/users/hch/dma-mapping.git
@@ -21618,7 +21608,6 @@ XEN SWIOTLB SUBSYSTEM
 M:	Juergen Gross <jgross@suse.com>
 M:	Stefano Stabellini <sstabellini@kernel.org>
 L:	xen-devel@lists.xenproject.org (moderated for non-subscribers)
-L:	iommu@lists.linux-foundation.org
 L:	iommu@lists.linux.dev
 S:	Supported
 F:	arch/x86/xen/*swiotlb*
diff --git a/Makefile b/Makefile
index 088b84f99203..323032d60ac3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 5
 PATCHLEVEL = 18
-SUBLEVEL = 10
+SUBLEVEL = 11
 EXTRAVERSION =
 NAME = Superb Owl
 
diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts
index 7719ea3d4933..81ccb0636a00 100644
--- a/arch/arm/boot/dts/at91-sam9x60ek.dts
+++ b/arch/arm/boot/dts/at91-sam9x60ek.dts
@@ -233,10 +233,9 @@ i2c0: i2c@600 {
 		status = "okay";
 
 		eeprom@53 {
-			compatible = "atmel,24c32";
+			compatible = "atmel,24c02";
 			reg = <0x53>;
 			pagesize = <16>;
-			size = <128>;
 			status = "okay";
 		};
 	};
diff --git a/arch/arm/boot/dts/at91-sama5d2_icp.dts b/arch/arm/boot/dts/at91-sama5d2_icp.dts
index 806eb1d911d7..164201a8fbf2 100644
--- a/arch/arm/boot/dts/at91-sama5d2_icp.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_icp.dts
@@ -329,21 +329,21 @@ &i2c1 {
 	status = "okay";
 
 	eeprom@50 {
-		compatible = "atmel,24c32";
+		compatible = "atmel,24c02";
 		reg = <0x50>;
 		pagesize = <16>;
 		status = "okay";
 	};
 
 	eeprom@52 {
-		compatible = "atmel,24c32";
+		compatible = "atmel,24c02";
 		reg = <0x52>;
 		pagesize = <16>;
 		status = "disabled";
 	};
 
 	eeprom@53 {
-		compatible = "atmel,24c32";
+		compatible = "atmel,24c02";
 		reg = <0x53>;
 		pagesize = <16>;
 		status = "disabled";
diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi
index f9aa9af31efd..9c2bbf115f4c 100644
--- a/arch/arm/boot/dts/stm32mp151.dtsi
+++ b/arch/arm/boot/dts/stm32mp151.dtsi
@@ -1474,7 +1474,7 @@ stmmac_axi_config_0: stmmac-axi-config {
 		usbh_ohci: usb@5800c000 {
 			compatible = "generic-ohci";
 			reg = <0x5800c000 0x1000>;
-			clocks = <&rcc USBH>, <&usbphyc>;
+			clocks = <&usbphyc>, <&rcc USBH>;
 			resets = <&rcc USBH_R>;
 			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
@@ -1483,7 +1483,7 @@ usbh_ohci: usb@5800c000 {
 		usbh_ehci: usb@5800d000 {
 			compatible = "generic-ehci";
 			reg = <0x5800d000 0x1000>;
-			clocks = <&rcc USBH>;
+			clocks = <&usbphyc>, <&rcc USBH>;
 			resets = <&rcc USBH_R>;
 			interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
 			companion = <&usbh_ohci>;
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index ca32446b187f..f53086ddc48b 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -93,6 +93,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
 CONFIG_DRM_MXSFB=y
+CONFIG_FB=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 0fd609e26615..32f224f723a5 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -146,7 +146,7 @@ static const struct wakeup_source_info ws_info[] = {
 
 static const struct of_device_id sama5d2_ws_ids[] = {
 	{ .compatible = "atmel,sama5d2-gem",		.data = &ws_info[0] },
-	{ .compatible = "atmel,at91rm9200-rtc",		.data = &ws_info[1] },
+	{ .compatible = "atmel,sama5d2-rtc",		.data = &ws_info[1] },
 	{ .compatible = "atmel,sama5d3-udc",		.data = &ws_info[2] },
 	{ .compatible = "atmel,at91rm9200-ohci",	.data = &ws_info[2] },
 	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
@@ -157,24 +157,24 @@ static const struct of_device_id sama5d2_ws_ids[] = {
 };
 
 static const struct of_device_id sam9x60_ws_ids[] = {
-	{ .compatible = "atmel,at91sam9x5-rtc",		.data = &ws_info[1] },
+	{ .compatible = "microchip,sam9x60-rtc",	.data = &ws_info[1] },
 	{ .compatible = "atmel,at91rm9200-ohci",	.data = &ws_info[2] },
 	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
 	{ .compatible = "atmel,at91sam9g45-ehci",	.data = &ws_info[2] },
 	{ .compatible = "usb-ehci",			.data = &ws_info[2] },
-	{ .compatible = "atmel,at91sam9260-rtt",	.data = &ws_info[4] },
+	{ .compatible = "microchip,sam9x60-rtt",	.data = &ws_info[4] },
 	{ .compatible = "cdns,sam9x60-macb",		.data = &ws_info[5] },
 	{ /* sentinel */ }
 };
 
 static const struct of_device_id sama7g5_ws_ids[] = {
-	{ .compatible = "atmel,at91sam9x5-rtc",		.data = &ws_info[1] },
+	{ .compatible = "microchip,sama7g5-rtc",	.data = &ws_info[1] },
 	{ .compatible = "microchip,sama7g5-ohci",	.data = &ws_info[2] },
 	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
 	{ .compatible = "atmel,at91sam9g45-ehci",	.data = &ws_info[2] },
 	{ .compatible = "usb-ehci",			.data = &ws_info[2] },
 	{ .compatible = "microchip,sama7g5-sdhci",	.data = &ws_info[3] },
-	{ .compatible = "atmel,at91sam9260-rtt",	.data = &ws_info[4] },
+	{ .compatible = "microchip,sama7g5-rtt",	.data = &ws_info[4] },
 	{ /* sentinel */ }
 };
 
diff --git a/arch/arm/mach-meson/platsmp.c b/arch/arm/mach-meson/platsmp.c
index 4b8ad728bb42..32ac60b89fdc 100644
--- a/arch/arm/mach-meson/platsmp.c
+++ b/arch/arm/mach-meson/platsmp.c
@@ -71,6 +71,7 @@ static void __init meson_smp_prepare_cpus(const char *scu_compatible,
 	}
 
 	sram_base = of_iomap(node, 0);
+	of_node_put(node);
 	if (!sram_base) {
 		pr_err("Couldn't map SRAM registers\n");
 		return;
@@ -91,6 +92,7 @@ static void __init meson_smp_prepare_cpus(const char *scu_compatible,
 	}
 
 	scu_base = of_iomap(node, 0);
+	of_node_put(node);
 	if (!scu_base) {
 		pr_err("Couldn't map SCU registers\n");
 		return;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index 4c3ac4214a2c..5744fa76e9b2 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -395,21 +395,21 @@ &wdog1 {
 &iomuxc {
 	pinctrl_eqos: eqosgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC				0x3
-			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO				0x3
-			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0			0x91
-			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1			0x91
-			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2			0x91
-			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3			0x91
-			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x91
-			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL			0x91
-			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0			0x1f
-			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1			0x1f
-			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2			0x1f
-			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3			0x1f
-			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL			0x1f
-			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x1f
-			MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22				0x19
+			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC				0x2
+			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO				0x2
+			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0			0x90
+			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1			0x90
+			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2			0x90
+			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3			0x90
+			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x90
+			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL			0x90
+			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0			0x16
+			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1			0x16
+			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2			0x16
+			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3			0x16
+			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL			0x16
+			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x16
+			MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22				0x10
 		>;
 	};
 
@@ -461,28 +461,28 @@ MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27      0x154   /* CAN2_STBY */
 
 	pinctrl_gpio_led: gpioledgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16	0x19
+			MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16	0x140
 		>;
 	};
 
 	pinctrl_i2c1: i2c1grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL		0x400001c3
-			MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA		0x400001c3
+			MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL		0x400001c2
+			MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA		0x400001c2
 		>;
 	};
 
 	pinctrl_i2c3: i2c3grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL		0x400001c3
-			MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA		0x400001c3
+			MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL		0x400001c2
+			MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA		0x400001c2
 		>;
 	};
 
 	pinctrl_i2c5: i2c5grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA         0x400001c3
-			MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL         0x400001c3
+			MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA         0x400001c2
+			MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL         0x400001c2
 		>;
 	};
 
@@ -500,20 +500,20 @@ MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12	0x146 /* Input pull-up. */
 
 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x41
+			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x40
 		>;
 	};
 
 	pinctrl_uart2: uart2grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX	0x49
-			MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX	0x49
+			MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX	0x140
+			MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX	0x140
 		>;
 	};
 
 	pinctrl_usb1_vbus: usb1grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR	0x19
+			MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR	0x10
 		>;
 	};
 
@@ -525,7 +525,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0	0x1d0
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d0
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d0
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d0
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
 		>;
 	};
 
@@ -537,7 +537,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0	0x1d4
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d4
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d4
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d4
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
 		>;
 	};
 
@@ -549,7 +549,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0	0x1d6
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d6
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d6
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d6
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index 984a6b9ded8d..6aa720bafe28 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -116,48 +116,48 @@ &usdhc2 {
 &iomuxc {
 	pinctrl_eqos: eqosgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC			0x3
-			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO			0x3
-			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0		0x91
-			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1		0x91
-			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2		0x91
-			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3		0x91
-			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x91
-			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL		0x91
-			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x1f
-			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x1f
-			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x1f
-			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x1f
-			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x1f
-			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x1f
+			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC			0x2
+			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO			0x2
+			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0		0x90
+			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1		0x90
+			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2		0x90
+			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3		0x90
+			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x90
+			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL		0x90
+			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x16
+			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x16
+			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x16
+			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x16
+			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x16
+			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x16
 			MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20			0x10
 		>;
 	};
 
 	pinctrl_i2c2: i2c2grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL		0x400001c3
-			MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA		0x400001c3
+			MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL		0x400001c2
+			MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA		0x400001c2
 		>;
 	};
 
 	pinctrl_i2c2_gpio: i2c2gpiogrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16	0x1e3
-			MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17	0x1e3
+			MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16	0x1e2
+			MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17	0x1e2
 		>;
 	};
 
 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x41
+			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x40
 		>;
 	};
 
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x49
-			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x49
+			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x40
+			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x40
 		>;
 	};
 
@@ -175,7 +175,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0	0x1d0
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d0
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d0
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d0
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
 		>;
 	};
 
@@ -187,7 +187,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0	0x1d4
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d4
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d4
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d4
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
 		>;
 	};
 
@@ -199,7 +199,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0	0x1d6
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d6
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d6
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d6
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
 		>;
 	};
 };
diff --git a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi
index 3b0cc85d6674..71e373b11de9 100644
--- a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi
@@ -74,7 +74,7 @@ pm8994_regulators: pm8994-regulators {
 		vdd_l17_29-supply = <&vph_pwr>;
 		vdd_l20_21-supply = <&vph_pwr>;
 		vdd_l25-supply = <&pm8994_s5>;
-		vdd_lvs1_2 = <&pm8994_s4>;
+		vdd_lvs1_2-supply = <&pm8994_s4>;
 
 		/* S1, S2, S6 and S12 are managed by RPMPD */
 
diff --git a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
index 84558ab5fe86..ae882bfbf48d 100644
--- a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
+++ b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
@@ -143,7 +143,7 @@ pm8994-regulators {
 		vdd_l17_29-supply = <&vph_pwr>;
 		vdd_l20_21-supply = <&vph_pwr>;
 		vdd_l25-supply = <&pm8994_s5>;
-		vdd_lvs1_2 = <&pm8994_s4>;
+		vdd_lvs1_2-supply = <&pm8994_s4>;
 
 		/* S1, S2, S6 and S12 are managed by RPMPD */
 
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
index b1e595cb4b90..6b76321288d0 100644
--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
@@ -93,7 +93,7 @@ CPU5: cpu@101 {
 		CPU6: cpu@102 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a57";
-			reg = <0x0 0x101>;
+			reg = <0x0 0x102>;
 			enable-method = "psci";
 			next-level-cache = <&L2_1>;
 		};
@@ -101,7 +101,7 @@ CPU6: cpu@102 {
 		CPU7: cpu@103 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a57";
-			reg = <0x0 0x101>;
+			reg = <0x0 0x103>;
 			enable-method = "psci";
 			next-level-cache = <&L2_1>;
 		};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index b31bf62e8680..ad21cf465c98 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -4238,7 +4238,7 @@ mdss: mdss@ae00000 {
 
 			power-domains = <&dispcc MDSS_GDSC>;
 
-			clocks = <&gcc GCC_DISP_AHB_CLK>,
+			clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
 				 <&dispcc DISP_CC_MDSS_MDP_CLK>;
 			clock-names = "iface", "core";
 
diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
index e63b7b0458cf..7a14eb89e4ca 100644
--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -1383,8 +1383,8 @@ ufs_mem_hc: ufshc@1d84000 {
 
 			iommus = <&apps_smmu 0xe0 0x0>;
 
-			interconnects = <&aggre1_noc MASTER_UFS_MEM &mc_virt SLAVE_EBI1>,
-					<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_UFS_MEM_CFG>;
+			interconnects = <&aggre1_noc MASTER_UFS_MEM 0 &mc_virt SLAVE_EBI1 0>,
+					<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_UFS_MEM_CFG 0>;
 			interconnect-names = "ufs-ddr", "cpu-ufs";
 			clock-names =
 				"core_clk",
diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c
index 463c78c52cc5..3805ad13b8f3 100644
--- a/arch/powerpc/platforms/powernv/rng.c
+++ b/arch/powerpc/platforms/powernv/rng.c
@@ -176,12 +176,8 @@ static int __init pnv_get_random_long_early(unsigned long *v)
 		    NULL) != pnv_get_random_long_early)
 		return 0;
 
-	for_each_compatible_node(dn, NULL, "ibm,power-rng") {
-		if (rng_create(dn))
-			continue;
-		/* Create devices for hwrng driver */
-		of_platform_device_create(dn, NULL, NULL);
-	}
+	for_each_compatible_node(dn, NULL, "ibm,power-rng")
+		rng_create(dn);
 
 	if (!ppc_md.get_random_seed)
 		return 0;
@@ -205,10 +201,18 @@ void __init pnv_rng_init(void)
 
 static int __init pnv_rng_late_init(void)
 {
+	struct device_node *dn;
 	unsigned long v;
+
 	/* In case it wasn't called during init for some other reason. */
 	if (ppc_md.get_random_seed == pnv_get_random_long_early)
 		pnv_get_random_long_early(&v);
+
+	if (ppc_md.get_random_seed == powernv_get_random_long) {
+		for_each_compatible_node(dn, NULL, "ibm,power-rng")
+			of_platform_device_create(dn, NULL, NULL);
+	}
+
 	return 0;
 }
 machine_subsys_initcall(powernv, pnv_rng_late_init);
diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
index df1644d9b3b6..3677df836e91 100644
--- a/arch/x86/kernel/acpi/cppc.c
+++ b/arch/x86/kernel/acpi/cppc.c
@@ -11,6 +11,16 @@
 
 /* Refer to drivers/acpi/cppc_acpi.c for the description of functions */
 
+bool cpc_supported_by_cpu(void)
+{
+	switch (boot_cpu_data.x86_vendor) {
+	case X86_VENDOR_AMD:
+	case X86_VENDOR_HYGON:
+		return boot_cpu_has(X86_FEATURE_CPPC);
+	}
+	return false;
+}
+
 bool cpc_ffh_supported(void)
 {
 	return true;
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 3e58b613a2c4..6c735cfa7d43 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -278,13 +278,27 @@ bool osc_sb_apei_support_acked;
 bool osc_pc_lpi_support_confirmed;
 EXPORT_SYMBOL_GPL(osc_pc_lpi_support_confirmed);
 
+/*
+ * ACPI 6.2 Section 6.2.11.2 'Platform-Wide OSPM Capabilities':
+ *   Starting with ACPI Specification 6.2, all _CPC registers can be in
+ *   PCC, System Memory, System IO, or Functional Fixed Hardware address
+ *   spaces. OSPM support for this more flexible register space scheme is
+ *   indicated by the “Flexible Address Space for CPPC Registers” _OSC bit.
+ *
+ * Otherwise (cf ACPI 6.1, s8.4.7.1.1.X), _CPC registers must be in:
+ * - PCC or Functional Fixed Hardware address space if defined
+ * - SystemMemory address space (NULL register) if not defined
+ */
+bool osc_cpc_flexible_adr_space_confirmed;
+EXPORT_SYMBOL_GPL(osc_cpc_flexible_adr_space_confirmed);
+
 /*
  * ACPI 6.4 Operating System Capabilities for USB.
  */
 bool osc_sb_native_usb4_support_confirmed;
 EXPORT_SYMBOL_GPL(osc_sb_native_usb4_support_confirmed);
 
-bool osc_sb_cppc_not_supported;
+bool osc_sb_cppc2_support_acked;
 
 static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
 static void acpi_bus_osc_negotiate_platform_control(void)
@@ -315,12 +329,15 @@ static void acpi_bus_osc_negotiate_platform_control(void)
 #endif
 #ifdef CONFIG_X86
 	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
-	if (boot_cpu_has(X86_FEATURE_HWP)) {
-		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT;
-		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT;
-	}
 #endif
 
+#ifdef CONFIG_ACPI_CPPC_LIB
+	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT;
+	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT;
+#endif
+
+	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
+
 	if (IS_ENABLED(CONFIG_SCHED_MC_PRIO))
 		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_DIVERSE_HIGH_SUPPORT;
 
@@ -341,12 +358,6 @@ static void acpi_bus_osc_negotiate_platform_control(void)
 		return;
 	}
 
-#ifdef CONFIG_X86
-	if (boot_cpu_has(X86_FEATURE_HWP))
-		osc_sb_cppc_not_supported = !(capbuf_ret[OSC_SUPPORT_DWORD] &
-				(OSC_SB_CPC_SUPPORT | OSC_SB_CPCV2_SUPPORT));
-#endif
-
 	/*
 	 * Now run _OSC again with query flag clear and with the caps
 	 * supported by both the OS and the platform.
@@ -360,12 +371,18 @@ static void acpi_bus_osc_negotiate_platform_control(void)
 
 	capbuf_ret = context.ret.pointer;
 	if (context.ret.length > OSC_SUPPORT_DWORD) {
+#ifdef CONFIG_ACPI_CPPC_LIB
+		osc_sb_cppc2_support_acked = capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPCV2_SUPPORT;
+#endif
+
 		osc_sb_apei_support_acked =
 			capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;
 		osc_pc_lpi_support_confirmed =
 			capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;
 		osc_sb_native_usb4_support_confirmed =
 			capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;
+		osc_cpc_flexible_adr_space_confirmed =
+			capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
 	}
 
 	kfree(context.ret.pointer);
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index 34576ab0e2e1..57ca7aa0e169 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -559,6 +559,19 @@ bool __weak cpc_ffh_supported(void)
 	return false;
 }
 
+/**
+ * cpc_supported_by_cpu() - check if CPPC is supported by CPU
+ *
+ * Check if the architectural support for CPPC is present even
+ * if the _OSC hasn't prescribed it
+ *
+ * Return: true for supported, false for not supported
+ */
+bool __weak cpc_supported_by_cpu(void)
+{
+	return false;
+}
+
 /**
  * pcc_data_alloc() - Allocate the pcc_data memory for pcc subspace
  *
@@ -666,8 +679,11 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
 	acpi_status status;
 	int ret = -ENODATA;
 
-	if (osc_sb_cppc_not_supported)
-		return -ENODEV;
+	if (!osc_sb_cppc2_support_acked) {
+		pr_debug("CPPC v2 _OSC not acked\n");
+		if (!cpc_supported_by_cpu())
+			return -ENODEV;
+	}
 
 	/* Parse the ACPI _CPC table for this CPU. */
 	status = acpi_evaluate_object_typed(handle, "_CPC", NULL, &output,
@@ -746,6 +762,11 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
 				if (gas_t->address) {
 					void __iomem *addr;
 
+					if (!osc_cpc_flexible_adr_space_confirmed) {
+						pr_debug("Flexible address space capability not supported\n");
+						goto out_free;
+					}
+
 					addr = ioremap(gas_t->address, gas_t->bit_width/8);
 					if (!addr)
 						goto out_free;
@@ -768,6 +789,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
 						 gas_t->address);
 					goto out_free;
 				}
+				if (!osc_cpc_flexible_adr_space_confirmed) {
+					pr_debug("Flexible address space capability not supported\n");
+					goto out_free;
+				}
 			} else {
 				if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) {
 					/* Support only PCC, SystemMemory, SystemIO, and FFH type regs. */
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 3d6430eb0c6a..9dc0ca3db61d 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -485,7 +485,18 @@ static void device_link_release_fn(struct work_struct *work)
 	/* Ensure that all references to the link object have been dropped. */
 	device_link_synchronize_removal();
 
-	pm_runtime_release_supplier(link, true);
+	pm_runtime_release_supplier(link);
+	/*
+	 * If supplier_preactivated is set, the link has been dropped between
+	 * the pm_runtime_get_suppliers() and pm_runtime_put_suppliers() calls
+	 * in __driver_probe_device().  In that case, drop the supplier's
+	 * PM-runtime usage counter to remove the reference taken by
+	 * pm_runtime_get_suppliers().
+	 */
+	if (link->supplier_preactivated)
+		pm_runtime_put_noidle(link->supplier);
+
+	pm_request_idle(link->supplier);
 
 	put_device(link->consumer);
 	put_device(link->supplier);
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index d4059e6ffeae..2e3aa9a2e33c 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -308,13 +308,10 @@ static int rpm_get_suppliers(struct device *dev)
 /**
  * pm_runtime_release_supplier - Drop references to device link's supplier.
  * @link: Target device link.
- * @check_idle: Whether or not to check if the supplier device is idle.
  *
- * Drop all runtime PM references associated with @link to its supplier device
- * and if @check_idle is set, check if that device is idle (and so it can be
- * suspended).
+ * Drop all runtime PM references associated with @link to its supplier device.
  */
-void pm_runtime_release_supplier(struct device_link *link, bool check_idle)
+void pm_runtime_release_supplier(struct device_link *link)
 {
 	struct device *supplier = link->supplier;
 
@@ -327,9 +324,6 @@ void pm_runtime_release_supplier(struct device_link *link, bool check_idle)
 	while (refcount_dec_not_one(&link->rpm_active) &&
 	       atomic_read(&supplier->power.usage_count) > 0)
 		pm_runtime_put_noidle(supplier);
-
-	if (check_idle)
-		pm_request_idle(supplier);
 }
 
 static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend)
@@ -337,8 +331,11 @@ static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend)
 	struct device_link *link;
 
 	list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
-				device_links_read_lock_held())
-		pm_runtime_release_supplier(link, try_to_suspend);
+				device_links_read_lock_held()) {
+		pm_runtime_release_supplier(link);
+		if (try_to_suspend)
+			pm_request_idle(link->supplier);
+	}
 }
 
 static void rpm_put_suppliers(struct device *dev)
@@ -1740,7 +1737,6 @@ void pm_runtime_get_suppliers(struct device *dev)
 		if (link->flags & DL_FLAG_PM_RUNTIME) {
 			link->supplier_preactivated = true;
 			pm_runtime_get_sync(link->supplier);
-			refcount_inc(&link->rpm_active);
 		}
 
 	device_links_read_unlock(idx);
@@ -1760,19 +1756,8 @@ void pm_runtime_put_suppliers(struct device *dev)
 	list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
 				device_links_read_lock_held())
 		if (link->supplier_preactivated) {
-			bool put;
-
 			link->supplier_preactivated = false;
-
-			spin_lock_irq(&dev->power.lock);
-
-			put = pm_runtime_status_suspended(dev) &&
-			      refcount_dec_not_one(&link->rpm_active);
-
-			spin_unlock_irq(&dev->power.lock);
-
-			if (put)
-				pm_runtime_put(link->supplier);
+			pm_runtime_put(link->supplier);
 		}
 
 	device_links_read_unlock(idx);
@@ -1807,7 +1792,8 @@ void pm_runtime_drop_link(struct device_link *link)
 		return;
 
 	pm_runtime_drop_link_count(link->consumer);
-	pm_runtime_release_supplier(link, true);
+	pm_runtime_release_supplier(link);
+	pm_request_idle(link->supplier);
 }
 
 static bool pm_runtime_need_not_resume(struct device *dev)
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index 5d33ce24fe09..ef68ee664b67 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -252,13 +252,13 @@ struct cxl_mbox_identify {
 } __packed;
 
 struct cxl_mbox_get_lsa {
-	u32 offset;
-	u32 length;
+	__le32 offset;
+	__le32 length;
 } __packed;
 
 struct cxl_mbox_set_lsa {
-	u32 offset;
-	u32 reserved;
+	__le32 offset;
+	__le32 reserved;
 	u8 data[];
 } __packed;
 
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index 44e899f06094..cb111bcfe8c6 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -46,6 +46,7 @@ static int create_endpoint(struct cxl_memdev *cxlmd,
 {
 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
 	struct cxl_port *endpoint;
+	int rc;
 
 	endpoint = devm_cxl_add_port(&parent_port->dev, &cxlmd->dev,
 				     cxlds->component_reg_phys, parent_port);
@@ -54,13 +55,17 @@ static int create_endpoint(struct cxl_memdev *cxlmd,
 
 	dev_dbg(&cxlmd->dev, "add: %s\n", dev_name(&endpoint->dev));
 
+	rc = cxl_endpoint_autoremove(cxlmd, endpoint);
+	if (rc)
+		return rc;
+
 	if (!endpoint->dev.driver) {
 		dev_err(&cxlmd->dev, "%s failed probe\n",
 			dev_name(&endpoint->dev));
 		return -ENXIO;
 	}
 
-	return cxl_endpoint_autoremove(cxlmd, endpoint);
+	return 0;
 }
 
 /**
diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c
index 15ad666ab03e..6d85b54747ab 100644
--- a/drivers/cxl/pmem.c
+++ b/drivers/cxl/pmem.c
@@ -108,8 +108,8 @@ static int cxl_pmem_get_config_data(struct cxl_dev_state *cxlds,
 		return -EINVAL;
 
 	get_lsa = (struct cxl_mbox_get_lsa) {
-		.offset = cmd->in_offset,
-		.length = cmd->in_length,
+		.offset = cpu_to_le32(cmd->in_offset),
+		.length = cpu_to_le32(cmd->in_length),
 	};
 
 	rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_LSA, &get_lsa,
@@ -139,7 +139,7 @@ static int cxl_pmem_set_config_data(struct cxl_dev_state *cxlds,
 		return -ENOMEM;
 
 	*set_lsa = (struct cxl_mbox_set_lsa) {
-		.offset = cmd->in_offset,
+		.offset = cpu_to_le32(cmd->in_offset),
 	};
 	memcpy(set_lsa->data, cmd->in_buf, cmd->in_length);
 
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index def564d1e8fa..678a3d4c6ec6 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -1893,6 +1893,11 @@ static int at_xdmac_alloc_chan_resources(struct dma_chan *chan)
 	for (i = 0; i < init_nr_desc_per_channel; i++) {
 		desc = at_xdmac_alloc_desc(chan, GFP_KERNEL);
 		if (!desc) {
+			if (i == 0) {
+				dev_warn(chan2dev(chan),
+					 "can't allocate any descriptors\n");
+				return -EIO;
+			}
 			dev_warn(chan2dev(chan),
 				"only %d descriptors have been allocated\n", i);
 			break;
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index e9c9bcb1f5c2..c741da02b67e 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -1164,8 +1164,9 @@ static int dma_chan_pause(struct dma_chan *dchan)
 			BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT;
 		axi_dma_iowrite32(chan->chip, DMAC_CHEN, val);
 	} else {
-		val = BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT |
-		      BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT;
+		val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG);
+		val |= BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT |
+			BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT;
 		axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, val);
 	}
 
@@ -1190,12 +1191,13 @@ static inline void axi_chan_resume(struct axi_dma_chan *chan)
 {
 	u32 val;
 
-	val = axi_dma_ioread32(chan->chip, DMAC_CHEN);
 	if (chan->chip->dw->hdata->reg_map_8_channels) {
+		val = axi_dma_ioread32(chan->chip, DMAC_CHEN);
 		val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP_SHIFT);
 		val |=  (BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT);
 		axi_dma_iowrite32(chan->chip, DMAC_CHEN, val);
 	} else {
+		val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG);
 		val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT);
 		val |=  (BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT);
 		axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, val);
diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
index f652da6ab47d..58490289efc3 100644
--- a/drivers/dma/idxd/device.c
+++ b/drivers/dma/idxd/device.c
@@ -698,10 +698,7 @@ static void idxd_device_wqs_clear_state(struct idxd_device *idxd)
 	for (i = 0; i < idxd->max_wqs; i++) {
 		struct idxd_wq *wq = idxd->wqs[i];
 
-		if (wq->state == IDXD_WQ_ENABLED) {
-			idxd_wq_disable_cleanup(wq);
-			wq->state = IDXD_WQ_DISABLED;
-		}
+		idxd_wq_disable_cleanup(wq);
 		idxd_wq_device_reset_cleanup(wq);
 	}
 }
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 6196a7b3956b..89694c704bd5 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -872,7 +872,7 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
 	 * SDMA stops cyclic channel when DMA request triggers a channel and no SDMA
 	 * owned buffer is available (i.e. BD_DONE was set too late).
 	 */
-	if (!is_sdma_channel_enabled(sdmac->sdma, sdmac->channel)) {
+	if (sdmac->desc && !is_sdma_channel_enabled(sdmac->sdma, sdmac->channel)) {
 		dev_warn(sdmac->sdma->dev, "restart cyclic channel %d\n", sdmac->channel);
 		sdma_enable_channel(sdmac->sdma, sdmac->channel);
 	}
@@ -2280,7 +2280,7 @@ MODULE_DESCRIPTION("i.MX SDMA driver");
 #if IS_ENABLED(CONFIG_SOC_IMX6Q)
 MODULE_FIRMWARE("imx/sdma/sdma-imx6q.bin");
 #endif
-#if IS_ENABLED(CONFIG_SOC_IMX7D)
+#if IS_ENABLED(CONFIG_SOC_IMX7D) || IS_ENABLED(CONFIG_SOC_IMX8M)
 MODULE_FIRMWARE("imx/sdma/sdma-imx7d.bin");
 #endif
 MODULE_LICENSE("GPL");
diff --git a/drivers/dma/lgm/lgm-dma.c b/drivers/dma/lgm/lgm-dma.c
index efe8bd3a0e2a..9b9184f964be 100644
--- a/drivers/dma/lgm/lgm-dma.c
+++ b/drivers/dma/lgm/lgm-dma.c
@@ -1593,11 +1593,12 @@ static int intel_ldma_probe(struct platform_device *pdev)
 	d->core_clk = devm_clk_get_optional(dev, NULL);
 	if (IS_ERR(d->core_clk))
 		return PTR_ERR(d->core_clk);
-	clk_prepare_enable(d->core_clk);
 
 	d->rst = devm_reset_control_get_optional(dev, NULL);
 	if (IS_ERR(d->rst))
 		return PTR_ERR(d->rst);
+
+	clk_prepare_enable(d->core_clk);
 	reset_control_deassert(d->rst);
 
 	ret = devm_add_action_or_reset(dev, ldma_clk_disable, d);
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 858400e42ec0..09915a5cba3e 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2589,7 +2589,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
 
 	/* If the DMAC pool is empty, alloc new */
 	if (!desc) {
-		DEFINE_SPINLOCK(lock);
+		static DEFINE_SPINLOCK(lock);
 		LIST_HEAD(pool);
 
 		if (!add_desc(&pool, &lock, GFP_ATOMIC, 1))
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 87f6ca1541cf..2ff787df513e 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -558,14 +558,6 @@ static int bam_alloc_chan(struct dma_chan *chan)
 	return 0;
 }
 
-static int bam_pm_runtime_get_sync(struct device *dev)
-{
-	if (pm_runtime_enabled(dev))
-		return pm_runtime_get_sync(dev);
-
-	return 0;
-}
-
 /**
  * bam_free_chan - Frees dma resources associated with specific channel
  * @chan: specified channel
@@ -581,7 +573,7 @@ static void bam_free_chan(struct dma_chan *chan)
 	unsigned long flags;
 	int ret;
 
-	ret = bam_pm_runtime_get_sync(bdev->dev);
+	ret = pm_runtime_get_sync(bdev->dev);
 	if (ret < 0)
 		return;
 
@@ -784,7 +776,7 @@ static int bam_pause(struct dma_chan *chan)
 	unsigned long flag;
 	int ret;
 
-	ret = bam_pm_runtime_get_sync(bdev->dev);
+	ret = pm_runtime_get_sync(bdev->dev);
 	if (ret < 0)
 		return ret;
 
@@ -810,7 +802,7 @@ static int bam_resume(struct dma_chan *chan)
 	unsigned long flag;
 	int ret;
 
-	ret = bam_pm_runtime_get_sync(bdev->dev);
+	ret = pm_runtime_get_sync(bdev->dev);
 	if (ret < 0)
 		return ret;
 
@@ -919,7 +911,7 @@ static irqreturn_t bam_dma_irq(int irq, void *data)
 	if (srcs & P_IRQ)
 		tasklet_schedule(&bdev->task);
 
-	ret = bam_pm_runtime_get_sync(bdev->dev);
+	ret = pm_runtime_get_sync(bdev->dev);
 	if (ret < 0)
 		return IRQ_NONE;
 
@@ -1037,7 +1029,7 @@ static void bam_start_dma(struct bam_chan *bchan)
 	if (!vd)
 		return;
 
-	ret = bam_pm_runtime_get_sync(bdev->dev);
+	ret = pm_runtime_get_sync(bdev->dev);
 	if (ret < 0)
 		return;
 
@@ -1374,11 +1366,6 @@ static int bam_dma_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_unregister_dma;
 
-	if (!bdev->bamclk) {
-		pm_runtime_disable(&pdev->dev);
-		return 0;
-	}
-
 	pm_runtime_irq_safe(&pdev->dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, BAM_DMA_AUTOSUSPEND_DELAY);
 	pm_runtime_use_autosuspend(&pdev->dev);
@@ -1462,10 +1449,8 @@ static int __maybe_unused bam_dma_suspend(struct device *dev)
 {
 	struct bam_device *bdev = dev_get_drvdata(dev);
 
-	if (bdev->bamclk) {
-		pm_runtime_force_suspend(dev);
-		clk_unprepare(bdev->bamclk);
-	}
+	pm_runtime_force_suspend(dev);
+	clk_unprepare(bdev->bamclk);
 
 	return 0;
 }
@@ -1475,13 +1460,11 @@ static int __maybe_unused bam_dma_resume(struct device *dev)
 	struct bam_device *bdev = dev_get_drvdata(dev);
 	int ret;
 
-	if (bdev->bamclk) {
-		ret = clk_prepare(bdev->bamclk);
-		if (ret)
-			return ret;
+	ret = clk_prepare(bdev->bamclk);
+	if (ret)
+		return ret;
 
-		pm_runtime_force_resume(dev);
-	}
+	pm_runtime_force_resume(dev);
 
 	return 0;
 }
diff --git a/drivers/dma/ti/dma-crossbar.c b/drivers/dma/ti/dma-crossbar.c
index 71d24fc07c00..f744ddbbbad7 100644
--- a/drivers/dma/ti/dma-crossbar.c
+++ b/drivers/dma/ti/dma-crossbar.c
@@ -245,6 +245,7 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec,
 	if (dma_spec->args[0] >= xbar->xbar_requests) {
 		dev_err(&pdev->dev, "Invalid XBAR request number: %d\n",
 			dma_spec->args[0]);
+		put_device(&pdev->dev);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -252,12 +253,14 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec,
 	dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
 	if (!dma_spec->np) {
 		dev_err(&pdev->dev, "Can't get DMA master\n");
+		put_device(&pdev->dev);
 		return ERR_PTR(-EINVAL);
 	}
 
 	map = kzalloc(sizeof(*map), GFP_KERNEL);
 	if (!map) {
 		of_node_put(dma_spec->np);
+		put_device(&pdev->dev);
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -268,6 +271,8 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec,
 		mutex_unlock(&xbar->mutex);
 		dev_err(&pdev->dev, "Run out of free DMA requests\n");
 		kfree(map);
+		of_node_put(dma_spec->np);
+		put_device(&pdev->dev);
 		return ERR_PTR(-ENOMEM);
 	}
 	set_bit(map->xbar_out, xbar->dma_inuse);
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
index b4c1ad19cdae..3d6f8ee355bf 100644
--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -1338,6 +1338,7 @@ static int cdns_i2c_probe(struct platform_device *pdev)
 	return 0;
 
 err_clk_dis:
+	clk_notifier_unregister(id->clk, &id->clk_rate_change_nb);
 	clk_disable_unprepare(id->clk);
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_set_suspended(&pdev->dev);
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index ac8e7d60672a..39cb1b7bb865 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -161,7 +161,6 @@ static const char *piix4_aux_port_name_sb800 = " port 1";
 
 struct sb800_mmio_cfg {
 	void __iomem *addr;
-	struct resource *res;
 	bool use_mmio;
 };
 
@@ -179,13 +178,11 @@ static int piix4_sb800_region_request(struct device *dev,
 				      struct sb800_mmio_cfg *mmio_cfg)
 {
 	if (mmio_cfg->use_mmio) {
-		struct resource *res;
 		void __iomem *addr;
 
-		res = request_mem_region_muxed(SB800_PIIX4_FCH_PM_ADDR,
-					       SB800_PIIX4_FCH_PM_SIZE,
-					       "sb800_piix4_smb");
-		if (!res) {
+		if (!request_mem_region_muxed(SB800_PIIX4_FCH_PM_ADDR,
+					      SB800_PIIX4_FCH_PM_SIZE,
+					      "sb800_piix4_smb")) {
 			dev_err(dev,
 				"SMBus base address memory region 0x%x already in use.\n",
 				SB800_PIIX4_FCH_PM_ADDR);
@@ -195,12 +192,12 @@ static int piix4_sb800_region_request(struct device *dev,
 		addr = ioremap(SB800_PIIX4_FCH_PM_ADDR,
 			       SB800_PIIX4_FCH_PM_SIZE);
 		if (!addr) {
-			release_resource(res);
+			release_mem_region(SB800_PIIX4_FCH_PM_ADDR,
+					   SB800_PIIX4_FCH_PM_SIZE);
 			dev_err(dev, "SMBus base address mapping failed.\n");
 			return -ENOMEM;
 		}
 
-		mmio_cfg->res = res;
 		mmio_cfg->addr = addr;
 
 		return 0;
@@ -222,7 +219,8 @@ static void piix4_sb800_region_release(struct device *dev,
 {
 	if (mmio_cfg->use_mmio) {
 		iounmap(mmio_cfg->addr);
-		release_resource(mmio_cfg->res);
+		release_mem_region(SB800_PIIX4_FCH_PM_ADDR,
+				   SB800_PIIX4_FCH_PM_SIZE);
 		return;
 	}
 
diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index 4de960834a1b..497c5bd95caf 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -383,7 +383,7 @@ static int dmar_pci_bus_notifier(struct notifier_block *nb,
 
 static struct notifier_block dmar_pci_bus_nb = {
 	.notifier_call = dmar_pci_bus_notifier,
-	.priority = INT_MIN,
+	.priority = 1,
 };
 
 static struct dmar_drhd_unit *
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index ba9a63cac47c..c7ec5177cf78 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -320,30 +320,6 @@ EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
 DEFINE_SPINLOCK(device_domain_lock);
 static LIST_HEAD(device_domain_list);
 
-/*
- * Iterate over elements in device_domain_list and call the specified
- * callback @fn against each element.
- */
-int for_each_device_domain(int (*fn)(struct device_domain_info *info,
-				     void *data), void *data)
-{
-	int ret = 0;
-	unsigned long flags;
-	struct device_domain_info *info;
-
-	spin_lock_irqsave(&device_domain_lock, flags);
-	list_for_each_entry(info, &device_domain_list, global) {
-		ret = fn(info, data);
-		if (ret) {
-			spin_unlock_irqrestore(&device_domain_lock, flags);
-			return ret;
-		}
-	}
-	spin_unlock_irqrestore(&device_domain_lock, flags);
-
-	return 0;
-}
-
 const struct iommu_ops intel_iommu_ops;
 
 static bool translation_pre_enabled(struct intel_iommu *iommu)
diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
index f8d215d85695..723f3cd8fe72 100644
--- a/drivers/iommu/intel/pasid.c
+++ b/drivers/iommu/intel/pasid.c
@@ -86,54 +86,6 @@ void vcmd_free_pasid(struct intel_iommu *iommu, u32 pasid)
 /*
  * Per device pasid table management:
  */
-static inline void
-device_attach_pasid_table(struct device_domain_info *info,
-			  struct pasid_table *pasid_table)
-{
-	info->pasid_table = pasid_table;
-	list_add(&info->table, &pasid_table->dev);
-}
-
-static inline void
-device_detach_pasid_table(struct device_domain_info *info,
-			  struct pasid_table *pasid_table)
-{
-	info->pasid_table = NULL;
-	list_del(&info->table);
-}
-
-struct pasid_table_opaque {
-	struct pasid_table	**pasid_table;
-	int			segment;
-	int			bus;
-	int			devfn;
-};
-
-static int search_pasid_table(struct device_domain_info *info, void *opaque)
-{
-	struct pasid_table_opaque *data = opaque;
-
-	if (info->iommu->segment == data->segment &&
-	    info->bus == data->bus &&
-	    info->devfn == data->devfn &&
-	    info->pasid_table) {
-		*data->pasid_table = info->pasid_table;
-		return 1;
-	}
-
-	return 0;
-}
-
-static int get_alias_pasid_table(struct pci_dev *pdev, u16 alias, void *opaque)
-{
-	struct pasid_table_opaque *data = opaque;
-
-	data->segment = pci_domain_nr(pdev->bus);
-	data->bus = PCI_BUS_NUM(alias);
-	data->devfn = alias & 0xff;
-
-	return for_each_device_domain(&search_pasid_table, data);
-}
 
 /*
  * Allocate a pasid table for @dev. It should be called in a
@@ -143,28 +95,18 @@ int intel_pasid_alloc_table(struct device *dev)
 {
 	struct device_domain_info *info;
 	struct pasid_table *pasid_table;
-	struct pasid_table_opaque data;
 	struct page *pages;
 	u32 max_pasid = 0;
-	int ret, order;
-	int size;
+	int order, size;
 
 	might_sleep();
 	info = dev_iommu_priv_get(dev);
 	if (WARN_ON(!info || !dev_is_pci(dev) || info->pasid_table))
 		return -EINVAL;
 
-	/* DMA alias device already has a pasid table, use it: */
-	data.pasid_table = &pasid_table;
-	ret = pci_for_each_dma_alias(to_pci_dev(dev),
-				     &get_alias_pasid_table, &data);
-	if (ret)
-		goto attach_out;
-
 	pasid_table = kzalloc(sizeof(*pasid_table), GFP_KERNEL);
 	if (!pasid_table)
 		return -ENOMEM;
-	INIT_LIST_HEAD(&pasid_table->dev);
 
 	if (info->pasid_supported)
 		max_pasid = min_t(u32, pci_max_pasids(to_pci_dev(dev)),
@@ -182,9 +124,7 @@ int intel_pasid_alloc_table(struct device *dev)
 	pasid_table->table = page_address(pages);
 	pasid_table->order = order;
 	pasid_table->max_pasid = 1 << (order + PAGE_SHIFT + 3);
-
-attach_out:
-	device_attach_pasid_table(info, pasid_table);
+	info->pasid_table = pasid_table;
 
 	return 0;
 }
@@ -202,10 +142,7 @@ void intel_pasid_free_table(struct device *dev)
 		return;
 
 	pasid_table = info->pasid_table;
-	device_detach_pasid_table(info, pasid_table);
-
-	if (!list_empty(&pasid_table->dev))
-		return;
+	info->pasid_table = NULL;
 
 	/* Free scalable mode PASID directory tables: */
 	dir = pasid_table->table;
diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h
index ab4408c824a5..3d62d84aced4 100644
--- a/drivers/iommu/intel/pasid.h
+++ b/drivers/iommu/intel/pasid.h
@@ -74,7 +74,6 @@ struct pasid_table {
 	void			*table;		/* pasid table pointer */
 	int			order;		/* page order of pasid table */
 	u32			max_pasid;	/* max pasid */
-	struct list_head	dev;		/* device list */
 };
 
 /* Get PRESENT bit of a PASID directory entry. */
diff --git a/drivers/misc/cardreader/rtsx_usb.c b/drivers/misc/cardreader/rtsx_usb.c
index 1ef9b61077c4..f150d8769f19 100644
--- a/drivers/misc/cardreader/rtsx_usb.c
+++ b/drivers/misc/cardreader/rtsx_usb.c
@@ -631,16 +631,20 @@ static int rtsx_usb_probe(struct usb_interface *intf,
 
 	ucr->pusb_dev = usb_dev;
 
-	ucr->iobuf = usb_alloc_coherent(ucr->pusb_dev, IOBUF_SIZE,
-			GFP_KERNEL, &ucr->iobuf_dma);
-	if (!ucr->iobuf)
+	ucr->cmd_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL);
+	if (!ucr->cmd_buf)
 		return -ENOMEM;
 
+	ucr->rsp_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL);
+	if (!ucr->rsp_buf) {
+		ret = -ENOMEM;
+		goto out_free_cmd_buf;
+	}
+
 	usb_set_intfdata(intf, ucr);
 
 	ucr->vendor_id = id->idVendor;
 	ucr->product_id = id->idProduct;
-	ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf;
 
 	mutex_init(&ucr->dev_mutex);
 
@@ -668,8 +672,11 @@ static int rtsx_usb_probe(struct usb_interface *intf,
 
 out_init_fail:
 	usb_set_intfdata(ucr->pusb_intf, NULL);
-	usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
-			ucr->iobuf_dma);
+	kfree(ucr->rsp_buf);
+	ucr->rsp_buf = NULL;
+out_free_cmd_buf:
+	kfree(ucr->cmd_buf);
+	ucr->cmd_buf = NULL;
 	return ret;
 }
 
@@ -682,8 +689,12 @@ static void rtsx_usb_disconnect(struct usb_interface *intf)
 	mfd_remove_devices(&intf->dev);
 
 	usb_set_intfdata(ucr->pusb_intf, NULL);
-	usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
-			ucr->iobuf_dma);
+
+	kfree(ucr->cmd_buf);
+	ucr->cmd_buf = NULL;
+
+	kfree(ucr->rsp_buf);
+	ucr->rsp_buf = NULL;
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
index 5215bd9b2c80..804dd1d48050 100644
--- a/drivers/net/can/grcan.c
+++ b/drivers/net/can/grcan.c
@@ -1646,7 +1646,6 @@ static int grcan_probe(struct platform_device *ofdev)
 	 */
 	sysid_parent = of_find_node_by_path("/ambapp0");
 	if (sysid_parent) {
-		of_node_get(sysid_parent);
 		err = of_property_read_u32(sysid_parent, "systemid", &sysid);
 		if (!err && ((sysid & GRLIB_VERSION_MASK) >=
 			     GRCAN_TXBUG_SAFE_GRLIB_VERSION))
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 088bb1bcf1ef..928958b7e6f6 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -532,7 +532,7 @@ static int m_can_read_fifo(struct net_device *dev, u32 rxfs)
 	/* acknowledge rx fifo 0 */
 	m_can_write(cdev, M_CAN_RXF0A, fgi);
 
-	timestamp = FIELD_GET(RX_BUF_RXTS_MASK, fifo_header.dlc);
+	timestamp = FIELD_GET(RX_BUF_RXTS_MASK, fifo_header.dlc) << 16;
 
 	m_can_receive_skb(cdev, skb, timestamp);
 
@@ -1036,7 +1036,7 @@ static int m_can_echo_tx_event(struct net_device *dev)
 		}
 
 		msg_mark = FIELD_GET(TX_EVENT_MM_MASK, txe);
-		timestamp = FIELD_GET(TX_EVENT_TXTS_MASK, txe);
+		timestamp = FIELD_GET(TX_EVENT_TXTS_MASK, txe) << 16;
 
 		/* ack txe element */
 		m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK,
@@ -1360,7 +1360,9 @@ static void m_can_chip_config(struct net_device *dev)
 	/* enable internal timestamp generation, with a prescalar of 16. The
 	 * prescalar is applied to the nominal bit timing
 	 */
-	m_can_write(cdev, M_CAN_TSCC, FIELD_PREP(TSCC_TCP_MASK, 0xf));
+	m_can_write(cdev, M_CAN_TSCC,
+		    FIELD_PREP(TSCC_TCP_MASK, 0xf) |
+		    FIELD_PREP(TSCC_TSS_MASK, TSCC_TSS_INTERNAL));
 
 	m_can_config_endisable(cdev, false);
 
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index 1e121e04208c..589996cef5db 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -1334,7 +1334,10 @@ static void rcar_canfd_set_bittiming(struct net_device *dev)
 		cfg = (RCANFD_DCFG_DTSEG1(gpriv, tseg1) | RCANFD_DCFG_DBRP(brp) |
 		       RCANFD_DCFG_DSJW(sjw) | RCANFD_DCFG_DTSEG2(gpriv, tseg2));
 
-		rcar_canfd_write(priv->base, RCANFD_F_DCFG(ch), cfg);
+		if (is_v3u(gpriv))
+			rcar_canfd_write(priv->base, RCANFD_V3U_DCFG(ch), cfg);
+		else
+			rcar_canfd_write(priv->base, RCANFD_F_DCFG(ch), cfg);
 		netdev_dbg(priv->ndev, "drate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n",
 			   brp, sjw, tseg1, tseg2);
 	} else {
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
index f9dd8fdba12b..1bbb43d77a72 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
@@ -12,6 +12,7 @@
 // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
 //
 
+#include <asm/unaligned.h>
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/device.h>
@@ -1641,6 +1642,7 @@ static int mcp251xfd_stop(struct net_device *ndev)
 	netif_stop_queue(ndev);
 	set_bit(MCP251XFD_FLAGS_DOWN, priv->flags);
 	hrtimer_cancel(&priv->rx_irq_timer);
+	hrtimer_cancel(&priv->tx_irq_timer);
 	mcp251xfd_chip_interrupts_disable(priv);
 	free_irq(ndev->irq, priv);
 	can_rx_offload_disable(&priv->offload);
@@ -1768,7 +1770,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id,
 	xfer[0].len = sizeof(buf_tx->cmd);
 	xfer[0].speed_hz = priv->spi_max_speed_hz_slow;
 	xfer[1].rx_buf = buf_rx->data;
-	xfer[1].len = sizeof(dev_id);
+	xfer[1].len = sizeof(*dev_id);
 	xfer[1].speed_hz = priv->spi_max_speed_hz_fast;
 
 	mcp251xfd_spi_cmd_read_nocrc(&buf_tx->cmd, MCP251XFD_REG_DEVID);
@@ -1777,7 +1779,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id,
 	if (err)
 		goto out_kfree_buf_tx;
 
-	*dev_id = be32_to_cpup((__be32 *)buf_rx->data);
+	*dev_id = get_unaligned_le32(buf_rx->data);
 	*effective_speed_hz_slow = xfer[0].effective_speed_hz;
 	*effective_speed_hz_fast = xfer[1].effective_speed_hz;
 
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
index 217510c12af5..92b7bc7f14b9 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
@@ -334,19 +334,21 @@ mcp251xfd_regmap_crc_read(void *context,
 		 * register. It increments once per SYS clock tick,
 		 * which is 20 or 40 MHz.
 		 *
-		 * Observation shows that if the lowest byte (which is
-		 * transferred first on the SPI bus) of that register
-		 * is 0x00 or 0x80 the calculated CRC doesn't always
-		 * match the transferred one.
+		 * Observation on the mcp2518fd shows that if the
+		 * lowest byte (which is transferred first on the SPI
+		 * bus) of that register is 0x00 or 0x80 the
+		 * calculated CRC doesn't always match the transferred
+		 * one. On the mcp2517fd this problem is not limited
+		 * to the first byte being 0x00 or 0x80.
 		 *
 		 * If the highest bit in the lowest byte is flipped
 		 * the transferred CRC matches the calculated one. We
-		 * assume for now the CRC calculation in the chip
-		 * works on wrong data and the transferred data is
-		 * correct.
+		 * assume for now the CRC operates on the correct
+		 * data.
 		 */
 		if (reg == MCP251XFD_REG_TBC &&
-		    (buf_rx->data[0] == 0x0 || buf_rx->data[0] == 0x80)) {
+		    ((buf_rx->data[0] & 0xf8) == 0x0 ||
+		     (buf_rx->data[0] & 0xf8) == 0x80)) {
 			/* Flip highest bit in lowest byte of le32 */
 			buf_rx->data[0] ^= 0x80;
 
@@ -356,10 +358,8 @@ mcp251xfd_regmap_crc_read(void *context,
 								  val_len);
 			if (!err) {
 				/* If CRC is now correct, assume
-				 * transferred data was OK, flip bit
-				 * back to original value.
+				 * flipped data is OK.
 				 */
-				buf_rx->data[0] ^= 0x80;
 				goto out;
 			}
 		}
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index b29ba9138866..d3a658b444b5 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -268,6 +268,8 @@ struct gs_can {
 
 	struct usb_anchor tx_submitted;
 	atomic_t active_tx_urbs;
+	void *rxbuf[GS_MAX_RX_URBS];
+	dma_addr_t rxbuf_dma[GS_MAX_RX_URBS];
 };
 
 /* usb interface struct */
@@ -742,6 +744,7 @@ static int gs_can_open(struct net_device *netdev)
 		for (i = 0; i < GS_MAX_RX_URBS; i++) {
 			struct urb *urb;
 			u8 *buf;
+			dma_addr_t buf_dma;
 
 			/* alloc rx urb */
 			urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -752,7 +755,7 @@ static int gs_can_open(struct net_device *netdev)
 			buf = usb_alloc_coherent(dev->udev,
 						 dev->parent->hf_size_rx,
 						 GFP_KERNEL,
-						 &urb->transfer_dma);
+						 &buf_dma);
 			if (!buf) {
 				netdev_err(netdev,
 					   "No memory left for USB buffer\n");
@@ -760,6 +763,8 @@ static int gs_can_open(struct net_device *netdev)
 				return -ENOMEM;
 			}
 
+			urb->transfer_dma = buf_dma;
+
 			/* fill, anchor, and submit rx urb */
 			usb_fill_bulk_urb(urb,
 					  dev->udev,
@@ -781,10 +786,17 @@ static int gs_can_open(struct net_device *netdev)
 					   "usb_submit failed (err=%d)\n", rc);
 
 				usb_unanchor_urb(urb);
+				usb_free_coherent(dev->udev,
+						  sizeof(struct gs_host_frame),
+						  buf,
+						  buf_dma);
 				usb_free_urb(urb);
 				break;
 			}
 
+			dev->rxbuf[i] = buf;
+			dev->rxbuf_dma[i] = buf_dma;
+
 			/* Drop reference,
 			 * USB core will take care of freeing it
 			 */
@@ -842,13 +854,20 @@ static int gs_can_close(struct net_device *netdev)
 	int rc;
 	struct gs_can *dev = netdev_priv(netdev);
 	struct gs_usb *parent = dev->parent;
+	unsigned int i;
 
 	netif_stop_queue(netdev);
 
 	/* Stop polling */
 	parent->active_channels--;
-	if (!parent->active_channels)
+	if (!parent->active_channels) {
 		usb_kill_anchored_urbs(&parent->rx_submitted);
+		for (i = 0; i < GS_MAX_RX_URBS; i++)
+			usb_free_coherent(dev->udev,
+					  sizeof(struct gs_host_frame),
+					  dev->rxbuf[i],
+					  dev->rxbuf_dma[i]);
+	}
 
 	/* Stop sending URBs */
 	usb_kill_anchored_urbs(&dev->tx_submitted);
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
index 3a49257f9fa6..eefcbe3aadce 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
@@ -35,9 +35,10 @@
 #define KVASER_USB_RX_BUFFER_SIZE		3072
 #define KVASER_USB_MAX_NET_DEVICES		5
 
-/* USB devices features */
-#define KVASER_USB_HAS_SILENT_MODE		BIT(0)
-#define KVASER_USB_HAS_TXRX_ERRORS		BIT(1)
+/* Kvaser USB device quirks */
+#define KVASER_USB_QUIRK_HAS_SILENT_MODE	BIT(0)
+#define KVASER_USB_QUIRK_HAS_TXRX_ERRORS	BIT(1)
+#define KVASER_USB_QUIRK_IGNORE_CLK_FREQ	BIT(2)
 
 /* Device capabilities */
 #define KVASER_USB_CAP_BERR_CAP			0x01
@@ -65,12 +66,7 @@ struct kvaser_usb_dev_card_data_hydra {
 struct kvaser_usb_dev_card_data {
 	u32 ctrlmode_supported;
 	u32 capabilities;
-	union {
-		struct {
-			enum kvaser_usb_leaf_family family;
-		} leaf;
-		struct kvaser_usb_dev_card_data_hydra hydra;
-	};
+	struct kvaser_usb_dev_card_data_hydra hydra;
 };
 
 /* Context for an outstanding, not yet ACKed, transmission */
@@ -83,7 +79,7 @@ struct kvaser_usb {
 	struct usb_device *udev;
 	struct usb_interface *intf;
 	struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES];
-	const struct kvaser_usb_dev_ops *ops;
+	const struct kvaser_usb_driver_info *driver_info;
 	const struct kvaser_usb_dev_cfg *cfg;
 
 	struct usb_endpoint_descriptor *bulk_in, *bulk_out;
@@ -165,6 +161,12 @@ struct kvaser_usb_dev_ops {
 				  u16 transid);
 };
 
+struct kvaser_usb_driver_info {
+	u32 quirks;
+	enum kvaser_usb_leaf_family family;
+	const struct kvaser_usb_dev_ops *ops;
+};
+
 struct kvaser_usb_dev_cfg {
 	const struct can_clock clock;
 	const unsigned int timestamp_freq;
@@ -184,4 +186,7 @@ int kvaser_usb_send_cmd_async(struct kvaser_usb_net_priv *priv, void *cmd,
 			      int len);
 
 int kvaser_usb_can_rx_over_error(struct net_device *netdev);
+
+extern const struct can_bittiming_const kvaser_usb_flexc_bittiming_const;
+
 #endif /* KVASER_USB_H */
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
index e67658b53d02..f211bfcb1d97 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
@@ -61,8 +61,6 @@
 #define USB_USBCAN_R_V2_PRODUCT_ID		294
 #define USB_LEAF_LIGHT_R_V2_PRODUCT_ID		295
 #define USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID	296
-#define USB_LEAF_PRODUCT_ID_END \
-	USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID
 
 /* Kvaser USBCan-II devices product ids */
 #define USB_USBCAN_REVB_PRODUCT_ID		2
@@ -89,116 +87,153 @@
 #define USB_USBCAN_PRO_4HS_PRODUCT_ID		276
 #define USB_HYBRID_CANLIN_PRODUCT_ID		277
 #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID	278
-#define USB_HYDRA_PRODUCT_ID_END \
-	USB_HYBRID_PRO_CANLIN_PRODUCT_ID
 
-static inline bool kvaser_is_leaf(const struct usb_device_id *id)
-{
-	return (id->idProduct >= USB_LEAF_DEVEL_PRODUCT_ID &&
-		id->idProduct <= USB_CAN_R_PRODUCT_ID) ||
-		(id->idProduct >= USB_LEAF_LITE_V2_PRODUCT_ID &&
-		 id->idProduct <= USB_LEAF_PRODUCT_ID_END);
-}
+static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = {
+	.quirks = 0,
+	.ops = &kvaser_usb_hydra_dev_ops,
+};
 
-static inline bool kvaser_is_usbcan(const struct usb_device_id *id)
-{
-	return id->idProduct >= USB_USBCAN_REVB_PRODUCT_ID &&
-	       id->idProduct <= USB_MEMORATOR_PRODUCT_ID;
-}
+static const struct kvaser_usb_driver_info kvaser_usb_driver_info_usbcan = {
+	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |
+		  KVASER_USB_QUIRK_HAS_SILENT_MODE,
+	.family = KVASER_USBCAN,
+	.ops = &kvaser_usb_leaf_dev_ops,
+};
 
-static inline bool kvaser_is_hydra(const struct usb_device_id *id)
-{
-	return id->idProduct >= USB_BLACKBIRD_V2_PRODUCT_ID &&
-	       id->idProduct <= USB_HYDRA_PRODUCT_ID_END;
-}
+static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf = {
+	.quirks = KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
+	.family = KVASER_LEAF,
+	.ops = &kvaser_usb_leaf_dev_ops,
+};
+
+static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = {
+	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |
+		  KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
+	.family = KVASER_LEAF,
+	.ops = &kvaser_usb_leaf_dev_ops,
+};
+
+static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_listen = {
+	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |
+		  KVASER_USB_QUIRK_HAS_SILENT_MODE |
+		  KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
+	.family = KVASER_LEAF,
+	.ops = &kvaser_usb_leaf_dev_ops,
+};
+
+static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = {
+	.quirks = 0,
+	.ops = &kvaser_usb_leaf_dev_ops,
+};
 
 static const struct usb_device_id kvaser_usb_table[] = {
-	/* Leaf USB product IDs */
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID) },
+	/* Leaf M32C USB product IDs */
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
-			       KVASER_USB_HAS_SILENT_MODE },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
-			       KVASER_USB_HAS_SILENT_MODE },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LS_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
-			       KVASER_USB_HAS_SILENT_MODE },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_SWC_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
-			       KVASER_USB_HAS_SILENT_MODE },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LIN_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
-			       KVASER_USB_HAS_SILENT_MODE },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_LS_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
-			       KVASER_USB_HAS_SILENT_MODE },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_SWC_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
-			       KVASER_USB_HAS_SILENT_MODE },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_DEVEL_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
-			       KVASER_USB_HAS_SILENT_MODE },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSHS_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
-			       KVASER_USB_HAS_SILENT_MODE },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_UPRO_HSHS_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID) },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_OBDII_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
-			       KVASER_USB_HAS_SILENT_MODE },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSLS_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_CH_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_SPRO_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_MERCURY_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_LEAF_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID) },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
+
+	/* Leaf i.MX28 USB product IDs */
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
 
 	/* USBCANII USB product IDs */
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_REVB_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMORATOR_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_VCI2_PRODUCT_ID),
-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },
 
 	/* Minihydra USB product IDs */
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_2CANLIN_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_2CANLIN_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100P_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100S_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_4HS_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID) },
-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID) },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_2CANLIN_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_2CANLIN_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100P_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100S_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_4HS_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID),
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, kvaser_usb_table);
@@ -285,6 +320,7 @@ int kvaser_usb_can_rx_over_error(struct net_device *netdev)
 static void kvaser_usb_read_bulk_callback(struct urb *urb)
 {
 	struct kvaser_usb *dev = urb->context;
+	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
 	int err;
 	unsigned int i;
 
@@ -301,8 +337,8 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb)
 		goto resubmit_urb;
 	}
 
-	dev->ops->dev_read_bulk_callback(dev, urb->transfer_buffer,
-					 urb->actual_length);
+	ops->dev_read_bulk_callback(dev, urb->transfer_buffer,
+				    urb->actual_length);
 
 resubmit_urb:
 	usb_fill_bulk_urb(urb, dev->udev,
@@ -396,6 +432,7 @@ static int kvaser_usb_open(struct net_device *netdev)
 {
 	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
 	struct kvaser_usb *dev = priv->dev;
+	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
 	int err;
 
 	err = open_candev(netdev);
@@ -406,11 +443,11 @@ static int kvaser_usb_open(struct net_device *netdev)
 	if (err)
 		goto error;
 
-	err = dev->ops->dev_set_opt_mode(priv);
+	err = ops->dev_set_opt_mode(priv);
 	if (err)
 		goto error;
 
-	err = dev->ops->dev_start_chip(priv);
+	err = ops->dev_start_chip(priv);
 	if (err) {
 		netdev_warn(netdev, "Cannot start device, error %d\n", err);
 		goto error;
@@ -467,22 +504,23 @@ static int kvaser_usb_close(struct net_device *netdev)
 {
 	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
 	struct kvaser_usb *dev = priv->dev;
+	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
 	int err;
 
 	netif_stop_queue(netdev);
 
-	err = dev->ops->dev_flush_queue(priv);
+	err = ops->dev_flush_queue(priv);
 	if (err)
 		netdev_warn(netdev, "Cannot flush queue, error %d\n", err);
 
-	if (dev->ops->dev_reset_chip) {
-		err = dev->ops->dev_reset_chip(dev, priv->channel);
+	if (ops->dev_reset_chip) {
+		err = ops->dev_reset_chip(dev, priv->channel);
 		if (err)
 			netdev_warn(netdev, "Cannot reset card, error %d\n",
 				    err);
 	}
 
-	err = dev->ops->dev_stop_chip(priv);
+	err = ops->dev_stop_chip(priv);
 	if (err)
 		netdev_warn(netdev, "Cannot stop device, error %d\n", err);
 
@@ -521,6 +559,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
 {
 	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
 	struct kvaser_usb *dev = priv->dev;
+	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
 	struct net_device_stats *stats = &netdev->stats;
 	struct kvaser_usb_tx_urb_context *context = NULL;
 	struct urb *urb;
@@ -563,8 +602,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
 		goto freeurb;
 	}
 
-	buf = dev->ops->dev_frame_to_cmd(priv, skb, &cmd_len,
-					 context->echo_index);
+	buf = ops->dev_frame_to_cmd(priv, skb, &cmd_len, context->echo_index);
 	if (!buf) {
 		stats->tx_dropped++;
 		dev_kfree_skb(skb);
@@ -648,15 +686,16 @@ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
 	}
 }
 
-static int kvaser_usb_init_one(struct kvaser_usb *dev,
-			       const struct usb_device_id *id, int channel)
+static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
 {
 	struct net_device *netdev;
 	struct kvaser_usb_net_priv *priv;
+	const struct kvaser_usb_driver_info *driver_info = dev->driver_info;
+	const struct kvaser_usb_dev_ops *ops = driver_info->ops;
 	int err;
 
-	if (dev->ops->dev_reset_chip) {
-		err = dev->ops->dev_reset_chip(dev, channel);
+	if (ops->dev_reset_chip) {
+		err = ops->dev_reset_chip(dev, channel);
 		if (err)
 			return err;
 	}
@@ -685,20 +724,19 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev,
 	priv->can.state = CAN_STATE_STOPPED;
 	priv->can.clock.freq = dev->cfg->clock.freq;
 	priv->can.bittiming_const = dev->cfg->bittiming_const;
-	priv->can.do_set_bittiming = dev->ops->dev_set_bittiming;
-	priv->can.do_set_mode = dev->ops->dev_set_mode;
-	if ((id->driver_info & KVASER_USB_HAS_TXRX_ERRORS) ||
+	priv->can.do_set_bittiming = ops->dev_set_bittiming;
+	priv->can.do_set_mode = ops->dev_set_mode;
+	if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) ||
 	    (priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP))
-		priv->can.do_get_berr_counter = dev->ops->dev_get_berr_counter;
-	if (id->driver_info & KVASER_USB_HAS_SILENT_MODE)
+		priv->can.do_get_berr_counter = ops->dev_get_berr_counter;
+	if (driver_info->quirks & KVASER_USB_QUIRK_HAS_SILENT_MODE)
 		priv->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY;
 
 	priv->can.ctrlmode_supported |= dev->card_data.ctrlmode_supported;
 
 	if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) {
 		priv->can.data_bittiming_const = dev->cfg->data_bittiming_const;
-		priv->can.do_set_data_bittiming =
-					dev->ops->dev_set_data_bittiming;
+		priv->can.do_set_data_bittiming = ops->dev_set_data_bittiming;
 	}
 
 	netdev->flags |= IFF_ECHO;
@@ -729,29 +767,22 @@ static int kvaser_usb_probe(struct usb_interface *intf,
 	struct kvaser_usb *dev;
 	int err;
 	int i;
+	const struct kvaser_usb_driver_info *driver_info;
+	const struct kvaser_usb_dev_ops *ops;
+
+	driver_info = (const struct kvaser_usb_driver_info *)id->driver_info;
+	if (!driver_info)
+		return -ENODEV;
 
 	dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
 		return -ENOMEM;
 
-	if (kvaser_is_leaf(id)) {
-		dev->card_data.leaf.family = KVASER_LEAF;
-		dev->ops = &kvaser_usb_leaf_dev_ops;
-	} else if (kvaser_is_usbcan(id)) {
-		dev->card_data.leaf.family = KVASER_USBCAN;
-		dev->ops = &kvaser_usb_leaf_dev_ops;
-	} else if (kvaser_is_hydra(id)) {
-		dev->ops = &kvaser_usb_hydra_dev_ops;
-	} else {
-		dev_err(&intf->dev,
-			"Product ID (%d) is not a supported Kvaser USB device\n",
-			id->idProduct);
-		return -ENODEV;
-	}
-
 	dev->intf = intf;
+	dev->driver_info = driver_info;
+	ops = driver_info->ops;
 
-	err = dev->ops->dev_setup_endpoints(dev);
+	err = ops->dev_setup_endpoints(dev);
 	if (err) {
 		dev_err(&intf->dev, "Cannot get usb endpoint(s)");
 		return err;
@@ -765,22 +796,22 @@ static int kvaser_usb_probe(struct usb_interface *intf,
 
 	dev->card_data.ctrlmode_supported = 0;
 	dev->card_data.capabilities = 0;
-	err = dev->ops->dev_init_card(dev);
+	err = ops->dev_init_card(dev);
 	if (err) {
 		dev_err(&intf->dev,
 			"Failed to initialize card, error %d\n", err);
 		return err;
 	}
 
-	err = dev->ops->dev_get_software_info(dev);
+	err = ops->dev_get_software_info(dev);
 	if (err) {
 		dev_err(&intf->dev,
 			"Cannot get software info, error %d\n", err);
 		return err;
 	}
 
-	if (dev->ops->dev_get_software_details) {
-		err = dev->ops->dev_get_software_details(dev);
+	if (ops->dev_get_software_details) {
+		err = ops->dev_get_software_details(dev);
 		if (err) {
 			dev_err(&intf->dev,
 				"Cannot get software details, error %d\n", err);
@@ -798,14 +829,14 @@ static int kvaser_usb_probe(struct usb_interface *intf,
 
 	dev_dbg(&intf->dev, "Max outstanding tx = %d URBs\n", dev->max_tx_urbs);
 
-	err = dev->ops->dev_get_card_info(dev);
+	err = ops->dev_get_card_info(dev);
 	if (err) {
 		dev_err(&intf->dev, "Cannot get card info, error %d\n", err);
 		return err;
 	}
 
-	if (dev->ops->dev_get_capabilities) {
-		err = dev->ops->dev_get_capabilities(dev);
+	if (ops->dev_get_capabilities) {
+		err = ops->dev_get_capabilities(dev);
 		if (err) {
 			dev_err(&intf->dev,
 				"Cannot get capabilities, error %d\n", err);
@@ -815,7 +846,7 @@ static int kvaser_usb_probe(struct usb_interface *intf,
 	}
 
 	for (i = 0; i < dev->nchannels; i++) {
-		err = kvaser_usb_init_one(dev, id, i);
+		err = kvaser_usb_init_one(dev, i);
 		if (err) {
 			kvaser_usb_remove_interfaces(dev);
 			return err;
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
index a26823c5b62a..5d70844ac030 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
@@ -375,7 +375,7 @@ static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = {
 	.brp_inc = 1,
 };
 
-static const struct can_bittiming_const kvaser_usb_hydra_flexc_bittiming_c = {
+const struct can_bittiming_const kvaser_usb_flexc_bittiming_const = {
 	.name = "kvaser_usb_flex",
 	.tseg1_min = 4,
 	.tseg1_max = 16,
@@ -2052,7 +2052,7 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc = {
 		.freq = 24 * MEGA /* Hz */,
 	},
 	.timestamp_freq = 1,
-	.bittiming_const = &kvaser_usb_hydra_flexc_bittiming_c,
+	.bittiming_const = &kvaser_usb_flexc_bittiming_const,
 };
 
 static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt = {
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
index c805b999c543..cc809ecd1e62 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
@@ -101,16 +101,6 @@
 #define USBCAN_ERROR_STATE_RX_ERROR	BIT(1)
 #define USBCAN_ERROR_STATE_BUSERROR	BIT(2)
 
-/* bittiming parameters */
-#define KVASER_USB_TSEG1_MIN		1
-#define KVASER_USB_TSEG1_MAX		16
-#define KVASER_USB_TSEG2_MIN		1
-#define KVASER_USB_TSEG2_MAX		8
-#define KVASER_USB_SJW_MAX		4
-#define KVASER_USB_BRP_MIN		1
-#define KVASER_USB_BRP_MAX		64
-#define KVASER_USB_BRP_INC		1
-
 /* ctrl modes */
 #define KVASER_CTRL_MODE_NORMAL		1
 #define KVASER_CTRL_MODE_SILENT		2
@@ -343,48 +333,68 @@ struct kvaser_usb_err_summary {
 	};
 };
 
-static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = {
-	.name = "kvaser_usb",
-	.tseg1_min = KVASER_USB_TSEG1_MIN,
-	.tseg1_max = KVASER_USB_TSEG1_MAX,
-	.tseg2_min = KVASER_USB_TSEG2_MIN,
-	.tseg2_max = KVASER_USB_TSEG2_MAX,
-	.sjw_max = KVASER_USB_SJW_MAX,
-	.brp_min = KVASER_USB_BRP_MIN,
-	.brp_max = KVASER_USB_BRP_MAX,
-	.brp_inc = KVASER_USB_BRP_INC,
+static const struct can_bittiming_const kvaser_usb_leaf_m16c_bittiming_const = {
+	.name = "kvaser_usb_ucii",
+	.tseg1_min = 4,
+	.tseg1_max = 16,
+	.tseg2_min = 2,
+	.tseg2_max = 8,
+	.sjw_max = 4,
+	.brp_min = 1,
+	.brp_max = 16,
+	.brp_inc = 1,
+};
+
+static const struct can_bittiming_const kvaser_usb_leaf_m32c_bittiming_const = {
+	.name = "kvaser_usb_leaf",
+	.tseg1_min = 3,
+	.tseg1_max = 16,
+	.tseg2_min = 2,
+	.tseg2_max = 8,
+	.sjw_max = 4,
+	.brp_min = 2,
+	.brp_max = 128,
+	.brp_inc = 2,
 };
 
-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_8mhz = {
+static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_usbcan_dev_cfg = {
 	.clock = {
 		.freq = 8 * MEGA /* Hz */,
 	},
 	.timestamp_freq = 1,
-	.bittiming_const = &kvaser_usb_leaf_bittiming_const,
+	.bittiming_const = &kvaser_usb_leaf_m16c_bittiming_const,
+};
+
+static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_m32c_dev_cfg = {
+	.clock = {
+		.freq = 16 * MEGA /* Hz */,
+	},
+	.timestamp_freq = 1,
+	.bittiming_const = &kvaser_usb_leaf_m32c_bittiming_const,
 };
 
-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_16mhz = {
+static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_16mhz = {
 	.clock = {
 		.freq = 16 * MEGA /* Hz */,
 	},
 	.timestamp_freq = 1,
-	.bittiming_const = &kvaser_usb_leaf_bittiming_const,
+	.bittiming_const = &kvaser_usb_flexc_bittiming_const,
 };
 
-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_24mhz = {
+static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_24mhz = {
 	.clock = {
 		.freq = 24 * MEGA /* Hz */,
 	},
 	.timestamp_freq = 1,
-	.bittiming_const = &kvaser_usb_leaf_bittiming_const,
+	.bittiming_const = &kvaser_usb_flexc_bittiming_const,
 };
 
-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_32mhz = {
+static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_32mhz = {
 	.clock = {
 		.freq = 32 * MEGA /* Hz */,
 	},
 	.timestamp_freq = 1,
-	.bittiming_const = &kvaser_usb_leaf_bittiming_const,
+	.bittiming_const = &kvaser_usb_flexc_bittiming_const,
 };
 
 static void *
@@ -404,7 +414,7 @@ kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
 				      sizeof(struct kvaser_cmd_tx_can);
 		cmd->u.tx_can.channel = priv->channel;
 
-		switch (dev->card_data.leaf.family) {
+		switch (dev->driver_info->family) {
 		case KVASER_LEAF:
 			cmd_tx_can_flags = &cmd->u.tx_can.leaf.flags;
 			break;
@@ -524,16 +534,23 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev,
 	dev->fw_version = le32_to_cpu(softinfo->fw_version);
 	dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx);
 
-	switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
-	case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
-		dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz;
-		break;
-	case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
-		dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz;
-		break;
-	case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
-		dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz;
-		break;
+	if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) {
+		/* Firmware expects bittiming parameters calculated for 16MHz
+		 * clock, regardless of the actual clock
+		 */
+		dev->cfg = &kvaser_usb_leaf_m32c_dev_cfg;
+	} else {
+		switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
+		case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
+			dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_16mhz;
+			break;
+		case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
+			dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_24mhz;
+			break;
+		case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
+			dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_32mhz;
+			break;
+		}
 	}
 }
 
@@ -550,7 +567,7 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
 	if (err)
 		return err;
 
-	switch (dev->card_data.leaf.family) {
+	switch (dev->driver_info->family) {
 	case KVASER_LEAF:
 		kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo);
 		break;
@@ -558,7 +575,7 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
 		dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version);
 		dev->max_tx_urbs =
 			le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx);
-		dev->cfg = &kvaser_usb_leaf_dev_cfg_8mhz;
+		dev->cfg = &kvaser_usb_leaf_usbcan_dev_cfg;
 		break;
 	}
 
@@ -597,7 +614,7 @@ static int kvaser_usb_leaf_get_card_info(struct kvaser_usb *dev)
 
 	dev->nchannels = cmd.u.cardinfo.nchannels;
 	if (dev->nchannels > KVASER_USB_MAX_NET_DEVICES ||
-	    (dev->card_data.leaf.family == KVASER_USBCAN &&
+	    (dev->driver_info->family == KVASER_USBCAN &&
 	     dev->nchannels > MAX_USBCAN_NET_DEVICES))
 		return -EINVAL;
 
@@ -730,7 +747,7 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
 	    new_state < CAN_STATE_BUS_OFF)
 		priv->can.can_stats.restarts++;
 
-	switch (dev->card_data.leaf.family) {
+	switch (dev->driver_info->family) {
 	case KVASER_LEAF:
 		if (es->leaf.error_factor) {
 			priv->can.can_stats.bus_error++;
@@ -809,7 +826,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
 		}
 	}
 
-	switch (dev->card_data.leaf.family) {
+	switch (dev->driver_info->family) {
 	case KVASER_LEAF:
 		if (es->leaf.error_factor) {
 			cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
@@ -999,7 +1016,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
 	stats = &priv->netdev->stats;
 
 	if ((cmd->u.rx_can_header.flag & MSG_FLAG_ERROR_FRAME) &&
-	    (dev->card_data.leaf.family == KVASER_LEAF &&
+	    (dev->driver_info->family == KVASER_LEAF &&
 	     cmd->id == CMD_LEAF_LOG_MESSAGE)) {
 		kvaser_usb_leaf_leaf_rx_error(dev, cmd);
 		return;
@@ -1015,7 +1032,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
 		return;
 	}
 
-	switch (dev->card_data.leaf.family) {
+	switch (dev->driver_info->family) {
 	case KVASER_LEAF:
 		rx_data = cmd->u.leaf.rx_can.data;
 		break;
@@ -1030,7 +1047,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
 		return;
 	}
 
-	if (dev->card_data.leaf.family == KVASER_LEAF && cmd->id ==
+	if (dev->driver_info->family == KVASER_LEAF && cmd->id ==
 	    CMD_LEAF_LOG_MESSAGE) {
 		cf->can_id = le32_to_cpu(cmd->u.leaf.log_message.id);
 		if (cf->can_id & KVASER_EXTENDED_FRAME)
@@ -1128,14 +1145,14 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
 		break;
 
 	case CMD_LEAF_LOG_MESSAGE:
-		if (dev->card_data.leaf.family != KVASER_LEAF)
+		if (dev->driver_info->family != KVASER_LEAF)
 			goto warn;
 		kvaser_usb_leaf_rx_can_msg(dev, cmd);
 		break;
 
 	case CMD_CHIP_STATE_EVENT:
 	case CMD_CAN_ERROR_EVENT:
-		if (dev->card_data.leaf.family == KVASER_LEAF)
+		if (dev->driver_info->family == KVASER_LEAF)
 			kvaser_usb_leaf_leaf_rx_error(dev, cmd);
 		else
 			kvaser_usb_leaf_usbcan_rx_error(dev, cmd);
@@ -1147,12 +1164,12 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
 
 	/* Ignored commands */
 	case CMD_USBCAN_CLOCK_OVERFLOW_EVENT:
-		if (dev->card_data.leaf.family != KVASER_USBCAN)
+		if (dev->driver_info->family != KVASER_USBCAN)
 			goto warn;
 		break;
 
 	case CMD_FLUSH_QUEUE_REPLY:
-		if (dev->card_data.leaf.family != KVASER_LEAF)
+		if (dev->driver_info->family != KVASER_LEAF)
 			goto warn;
 		break;
 
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 22b328bd7cd5..8c93dd710efc 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -2372,7 +2372,7 @@ static int
 qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
 {
 	struct qca8k_priv *priv = ds->priv;
-	int i, mtu = 0;
+	int ret, i, mtu = 0;
 
 	priv->port_mtu[port] = new_mtu;
 
@@ -2380,8 +2380,27 @@ qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
 		if (priv->port_mtu[i] > mtu)
 			mtu = priv->port_mtu[i];
 
+	/* To change the MAX_FRAME_SIZE the cpu ports must be off or
+	 * the switch panics.
+	 * Turn off both cpu ports before applying the new value to prevent
+	 * this.
+	 */
+	if (priv->port_sts[0].enabled)
+		qca8k_port_set_status(priv, 0, 0);
+
+	if (priv->port_sts[6].enabled)
+		qca8k_port_set_status(priv, 6, 0);
+
 	/* Include L2 header / FCS length */
-	return qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
+	ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
+
+	if (priv->port_sts[0].enabled)
+		qca8k_port_set_status(priv, 0, 1);
+
+	if (priv->port_sts[6].enabled)
+		qca8k_port_set_status(priv, 6, 1);
+
+	return ret;
 }
 
 static int
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 5c5931dba51d..c4221f89ab18 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -5774,6 +5774,15 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
 			release_sub_crqs(adapter, 0);
 			rc = init_sub_crqs(adapter);
 		} else {
+			/* no need to reinitialize completely, but we do
+			 * need to clean up transmits that were in flight
+			 * when we processed the reset.  Failure to do so
+			 * will confound the upper layer, usually TCP, by
+			 * creating the illusion of transmits that are
+			 * awaiting completion.
+			 */
+			clean_tx_pools(adapter);
+
 			rc = reset_sub_crq_queues(adapter);
 		}
 	} else {
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index 55c6bce5da61..615aff0798d3 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -37,6 +37,7 @@
 #include <net/tc_act/tc_mirred.h>
 #include <net/udp_tunnel.h>
 #include <net/xdp_sock.h>
+#include <linux/bitfield.h>
 #include "i40e_type.h"
 #include "i40e_prototype.h"
 #include <linux/net/intel/i40e_client.h>
@@ -1091,6 +1092,21 @@ static inline void i40e_write_fd_input_set(struct i40e_pf *pf,
 			  (u32)(val & 0xFFFFFFFFULL));
 }
 
+/**
+ * i40e_get_pf_count - get PCI PF count.
+ * @hw: pointer to a hw.
+ *
+ * Reports the function number of the highest PCI physical
+ * function plus 1 as it is loaded from the NVM.
+ *
+ * Return: PCI PF count.
+ **/
+static inline u32 i40e_get_pf_count(struct i40e_hw *hw)
+{
+	return FIELD_GET(I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK,
+			 rd32(hw, I40E_GLGEN_PCIFCNCNT));
+}
+
 /* needed by i40e_ethtool.c */
 int i40e_up(struct i40e_vsi *vsi);
 void i40e_down(struct i40e_vsi *vsi);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 46bb1169a004..77eb9c726205 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -549,6 +549,47 @@ void i40e_pf_reset_stats(struct i40e_pf *pf)
 	pf->hw_csum_rx_error = 0;
 }
 
+/**
+ * i40e_compute_pci_to_hw_id - compute index form PCI function.
+ * @vsi: ptr to the VSI to read from.
+ * @hw: ptr to the hardware info.
+ **/
+static u32 i40e_compute_pci_to_hw_id(struct i40e_vsi *vsi, struct i40e_hw *hw)
+{
+	int pf_count = i40e_get_pf_count(hw);
+
+	if (vsi->type == I40E_VSI_SRIOV)
+		return (hw->port * BIT(7)) / pf_count + vsi->vf_id;
+
+	return hw->port + BIT(7);
+}
+
+/**
+ * i40e_stat_update64 - read and update a 64 bit stat from the chip.
+ * @hw: ptr to the hardware info.
+ * @hireg: the high 32 bit reg to read.
+ * @loreg: the low 32 bit reg to read.
+ * @offset_loaded: has the initial offset been loaded yet.
+ * @offset: ptr to current offset value.
+ * @stat: ptr to the stat.
+ *
+ * Since the device stats are not reset at PFReset, they will not
+ * be zeroed when the driver starts.  We'll save the first values read
+ * and use them as offsets to be subtracted from the raw values in order
+ * to report stats that count from zero.
+ **/
+static void i40e_stat_update64(struct i40e_hw *hw, u32 hireg, u32 loreg,
+			       bool offset_loaded, u64 *offset, u64 *stat)
+{
+	u64 new_data;
+
+	new_data = rd64(hw, loreg);
+
+	if (!offset_loaded || new_data < *offset)
+		*offset = new_data;
+	*stat = new_data - *offset;
+}
+
 /**
  * i40e_stat_update48 - read and update a 48 bit stat from the chip
  * @hw: ptr to the hardware info
@@ -620,6 +661,34 @@ static void i40e_stat_update_and_clear32(struct i40e_hw *hw, u32 reg, u64 *stat)
 	*stat += new_data;
 }
 
+/**
+ * i40e_stats_update_rx_discards - update rx_discards.
+ * @vsi: ptr to the VSI to be updated.
+ * @hw: ptr to the hardware info.
+ * @stat_idx: VSI's stat_counter_idx.
+ * @offset_loaded: ptr to the VSI's stat_offsets_loaded.
+ * @stat_offset: ptr to stat_offset to store first read of specific register.
+ * @stat: ptr to VSI's stat to be updated.
+ **/
+static void
+i40e_stats_update_rx_discards(struct i40e_vsi *vsi, struct i40e_hw *hw,
+			      int stat_idx, bool offset_loaded,
+			      struct i40e_eth_stats *stat_offset,
+			      struct i40e_eth_stats *stat)
+{
+	u64 rx_rdpc, rx_rxerr;
+
+	i40e_stat_update32(hw, I40E_GLV_RDPC(stat_idx), offset_loaded,
+			   &stat_offset->rx_discards, &rx_rdpc);
+	i40e_stat_update64(hw,
+			   I40E_GL_RXERR1H(i40e_compute_pci_to_hw_id(vsi, hw)),
+			   I40E_GL_RXERR1L(i40e_compute_pci_to_hw_id(vsi, hw)),
+			   offset_loaded, &stat_offset->rx_discards_other,
+			   &rx_rxerr);
+
+	stat->rx_discards = rx_rdpc + rx_rxerr;
+}
+
 /**
  * i40e_update_eth_stats - Update VSI-specific ethernet statistics counters.
  * @vsi: the VSI to be updated
@@ -679,6 +748,10 @@ void i40e_update_eth_stats(struct i40e_vsi *vsi)
 			   I40E_GLV_BPTCL(stat_idx),
 			   vsi->stat_offsets_loaded,
 			   &oes->tx_broadcast, &es->tx_broadcast);
+
+	i40e_stats_update_rx_discards(vsi, hw, stat_idx,
+				      vsi->stat_offsets_loaded, oes, es);
+
 	vsi->stat_offsets_loaded = true;
 }
 
diff --git a/drivers/net/ethernet/intel/i40e/i40e_register.h b/drivers/net/ethernet/intel/i40e/i40e_register.h
index 1908eed4fa5e..7339003aa17c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_register.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_register.h
@@ -211,6 +211,11 @@
 #define I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT 0
 #define I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT 16
 #define I40E_GLGEN_MSRWD_MDIRDDATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT)
+#define I40E_GLGEN_PCIFCNCNT                0x001C0AB4 /* Reset: PCIR */
+#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT 0
+#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK  I40E_MASK(0x1F, I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT)
+#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT 16
+#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_MASK  I40E_MASK(0xFF, I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT)
 #define I40E_GLGEN_RSTAT 0x000B8188 /* Reset: POR */
 #define I40E_GLGEN_RSTAT_DEVSTATE_SHIFT 0
 #define I40E_GLGEN_RSTAT_DEVSTATE_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_DEVSTATE_SHIFT)
@@ -643,6 +648,14 @@
 #define I40E_VFQF_HKEY1_MAX_INDEX 12
 #define I40E_VFQF_HLUT1(_i, _VF) (0x00220000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */ /* Reset: CORER */
 #define I40E_VFQF_HLUT1_MAX_INDEX 15
+#define I40E_GL_RXERR1H(_i)             (0x00318004 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
+#define I40E_GL_RXERR1H_MAX_INDEX       143
+#define I40E_GL_RXERR1H_RXERR1H_SHIFT   0
+#define I40E_GL_RXERR1H_RXERR1H_MASK    I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1H_RXERR1H_SHIFT)
+#define I40E_GL_RXERR1L(_i)             (0x00318000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
+#define I40E_GL_RXERR1L_MAX_INDEX       143
+#define I40E_GL_RXERR1L_RXERR1L_SHIFT   0
+#define I40E_GL_RXERR1L_RXERR1L_MASK    I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1L_RXERR1L_SHIFT)
 #define I40E_GLPRT_BPRCH(_i) (0x003005E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
 #define I40E_GLPRT_BPRCL(_i) (0x003005E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
 #define I40E_GLPRT_BPTCH(_i) (0x00300A04 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 36a4ca1ffb1a..7b3f30beb757 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -1172,6 +1172,7 @@ struct i40e_eth_stats {
 	u64 tx_broadcast;		/* bptc */
 	u64 tx_discards;		/* tdpc */
 	u64 tx_errors;			/* tepc */
+	u64 rx_discards_other;          /* rxerr1 */
 };
 
 /* Statistics collected per VEB per TC */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 033ea71763e3..86b0f21287dc 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -2147,6 +2147,10 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
 		/* VFs only use TC 0 */
 		vfres->vsi_res[0].qset_handle
 					  = le16_to_cpu(vsi->info.qs_handle[0]);
+		if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) {
+			i40e_del_mac_filter(vsi, vf->default_lan_addr.addr);
+			eth_zero_addr(vf->default_lan_addr.addr);
+		}
 		ether_addr_copy(vfres->vsi_res[0].default_mac_addr,
 				vf->default_lan_addr.addr);
 	}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index ec2dfecd7f0f..c01651047448 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -4503,13 +4503,6 @@ static int mlx5e_policer_validate(const struct flow_action *action,
 		return -EOPNOTSUPP;
 	}
 
-	if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
-	    act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
-		NL_SET_ERR_MSG_MOD(extack,
-				   "Offload not supported when conform action is not pipe or ok");
-		return -EOPNOTSUPP;
-	}
-
 	if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
 	    !flow_action_is_last_entry(action, act)) {
 		NL_SET_ERR_MSG_MOD(extack,
@@ -4560,6 +4553,12 @@ static int scan_tc_matchall_fdb_actions(struct mlx5e_priv *priv,
 	flow_action_for_each(i, act, flow_action) {
 		switch (act->id) {
 		case FLOW_ACTION_POLICE:
+			if (act->police.notexceed.act_id != FLOW_ACTION_CONTINUE) {
+				NL_SET_ERR_MSG_MOD(extack,
+						   "Offload not supported when conform action is not continue");
+				return -EOPNOTSUPP;
+			}
+
 			err = mlx5e_policer_validate(flow_action, act, extack);
 			if (err)
 				return err;
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index f180a157eea4..05d759ba0c5c 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -979,7 +979,7 @@ static int lan966x_probe(struct platform_device *pdev)
 	struct fwnode_handle *ports, *portnp;
 	struct lan966x *lan966x;
 	u8 mac_addr[ETH_ALEN];
-	int err, i;
+	int err;
 
 	lan966x = devm_kzalloc(&pdev->dev, sizeof(*lan966x), GFP_KERNEL);
 	if (!lan966x)
@@ -1010,11 +1010,7 @@ static int lan966x_probe(struct platform_device *pdev)
 	if (err)
 		return dev_err_probe(&pdev->dev, err, "Reset failed");
 
-	i = 0;
-	fwnode_for_each_available_child_node(ports, portnp)
-		++i;
-
-	lan966x->num_phys_ports = i;
+	lan966x->num_phys_ports = NUM_PHYS_PORTS;
 	lan966x->ports = devm_kcalloc(&pdev->dev, lan966x->num_phys_ports,
 				      sizeof(struct lan966x_port *),
 				      GFP_KERNEL);
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index ae282da1da74..a240f13e052b 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -31,6 +31,7 @@
 /* Reserved amount for (SRC, PRIO) at index 8*SRC + PRIO */
 #define QSYS_Q_RSRV			95
 
+#define NUM_PHYS_PORTS			8
 #define CPU_PORT			8
 
 /* Reserved PGIDs */
diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
index 33f5c5698ccb..642e435c7031 100644
--- a/drivers/net/ethernet/realtek/r8169_main.c
+++ b/drivers/net/ethernet/realtek/r8169_main.c
@@ -4190,7 +4190,6 @@ static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts)
 static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
 				struct sk_buff *skb, u32 *opts)
 {
-	u32 transport_offset = (u32)skb_transport_offset(skb);
 	struct skb_shared_info *shinfo = skb_shinfo(skb);
 	u32 mss = shinfo->gso_size;
 
@@ -4207,7 +4206,7 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
 			WARN_ON_ONCE(1);
 		}
 
-		opts[0] |= transport_offset << GTTCPHO_SHIFT;
+		opts[0] |= skb_transport_offset(skb) << GTTCPHO_SHIFT;
 		opts[1] |= mss << TD1_MSS_SHIFT;
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		u8 ip_protocol;
@@ -4235,7 +4234,7 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
 		else
 			WARN_ON_ONCE(1);
 
-		opts[1] |= transport_offset << TCPHO_SHIFT;
+		opts[1] |= skb_transport_offset(skb) << TCPHO_SHIFT;
 	} else {
 		unsigned int padto = rtl_quirk_packet_padto(tp, skb);
 
@@ -4402,14 +4401,13 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
 						struct net_device *dev,
 						netdev_features_t features)
 {
-	int transport_offset = skb_transport_offset(skb);
 	struct rtl8169_private *tp = netdev_priv(dev);
 
 	if (skb_is_gso(skb)) {
 		if (tp->mac_version == RTL_GIGA_MAC_VER_34)
 			features = rtl8168evl_fix_tso(skb, features);
 
-		if (transport_offset > GTTCPHO_MAX &&
+		if (skb_transport_offset(skb) > GTTCPHO_MAX &&
 		    rtl_chip_supports_csum_v2(tp))
 			features &= ~NETIF_F_ALL_TSO;
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -4420,7 +4418,7 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
 		if (rtl_quirk_packet_padto(tp, skb))
 			features &= ~NETIF_F_CSUM_MASK;
 
-		if (transport_offset > TCPHO_MAX &&
+		if (skb_transport_offset(skb) > TCPHO_MAX &&
 		    rtl_chip_supports_csum_v2(tp))
 			features &= ~NETIF_F_CSUM_MASK;
 	}
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 2ea81931543c..9b2bd09628a3 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -2137,7 +2137,7 @@ static void usbnet_async_cmd_cb(struct urb *urb)
 int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
 			   u16 value, u16 index, const void *data, u16 size)
 {
-	struct usb_ctrlrequest *req = NULL;
+	struct usb_ctrlrequest *req;
 	struct urb *urb;
 	int err = -ENOMEM;
 	void *buf = NULL;
@@ -2155,7 +2155,7 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
 		if (!buf) {
 			netdev_err(dev->net, "Error allocating buffer"
 				   " in %s!\n", __func__);
-			goto fail_free;
+			goto fail_free_urb;
 		}
 	}
 
@@ -2179,14 +2179,21 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
 	if (err < 0) {
 		netdev_err(dev->net, "Error submitting the control"
 			   " message: status=%d\n", err);
-		goto fail_free;
+		goto fail_free_all;
 	}
 	return 0;
 
+fail_free_all:
+	kfree(req);
 fail_free_buf:
 	kfree(buf);
-fail_free:
-	kfree(req);
+	/*
+	 * avoid a double free
+	 * needed because the flag can be set only
+	 * after filling the URB
+	 */
+	urb->transfer_flags = 0;
+fail_free_urb:
 	usb_free_urb(urb);
 fail:
 	return err;
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
index 4ada80317a3b..b5c1a8f363f3 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
@@ -158,26 +158,26 @@ static const struct sunxi_desc_pin sun8i_a83t_pins[] = {
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ6 */
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ6 */
 		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D6 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ7 */
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ7 */
 		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D7 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "nand"),		/* DQS */
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQS */
 		  SUNXI_FUNCTION(0x3, "mmc2")),		/* RST */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "nand")),		/* CE2 */
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* CE2 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "nand")),		/* CE3 */
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* CE3 */
 	/* Hole */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index d9327d7d56ee..dd928402af99 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -544,6 +544,8 @@ static int sunxi_pconf_set(struct pinctrl_dev *pctldev, unsigned pin,
 	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	int i;
 
+	pin -= pctl->desc->pin_base;
+
 	for (i = 0; i < num_configs; i++) {
 		enum pin_config_param param;
 		unsigned long flags;
diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c
index b2d365ae0282..dae8a2e0f745 100644
--- a/drivers/soc/atmel/soc.c
+++ b/drivers/soc/atmel/soc.c
@@ -91,14 +91,14 @@ static const struct at91_soc socs[] __initconst = {
 	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
 		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
 		 "sam9x60", "sam9x60"),
-	AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D5M_EXID_MATCH,
-		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
+	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
+		 AT91_CIDR_VERSION_MASK, SAM9X60_D5M_EXID_MATCH,
 		 "sam9x60 64MiB DDR2 SiP", "sam9x60"),
-	AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D1G_EXID_MATCH,
-		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
+	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
+		 AT91_CIDR_VERSION_MASK, SAM9X60_D1G_EXID_MATCH,
 		 "sam9x60 128MiB DDR2 SiP", "sam9x60"),
-	AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D6K_EXID_MATCH,
-		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
+	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
+		 AT91_CIDR_VERSION_MASK, SAM9X60_D6K_EXID_MATCH,
 		 "sam9x60 8MiB SDRAM SiP", "sam9x60"),
 #endif
 #ifdef CONFIG_SOC_SAMA5
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 9a8ae6fa6ecb..526a7d2de491 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -2480,6 +2480,11 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
 	if (charcount != 256 && charcount != 512)
 		return -EINVAL;
 
+	/* font bigger than screen resolution ? */
+	if (w > FBCON_SWAP(info->var.rotate, info->var.xres, info->var.yres) ||
+	    h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres))
+		return -EINVAL;
+
 	/* Make sure drawing engine can handle the font */
 	if (!(info->pixmap.blit_x & (1 << (font->width - 1))) ||
 	    !(info->pixmap.blit_y & (1 << (font->height - 1))))
@@ -2742,6 +2747,34 @@ void fbcon_update_vcs(struct fb_info *info, bool all)
 }
 EXPORT_SYMBOL(fbcon_update_vcs);
 
+/* let fbcon check if it supports a new screen resolution */
+int fbcon_modechange_possible(struct fb_info *info, struct fb_var_screeninfo *var)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct vc_data *vc;
+	unsigned int i;
+
+	WARN_CONSOLE_UNLOCKED();
+
+	if (!ops)
+		return 0;
+
+	/* prevent setting a screen size which is smaller than font size */
+	for (i = first_fb_vc; i <= last_fb_vc; i++) {
+		vc = vc_cons[i].d;
+		if (!vc || vc->vc_mode != KD_TEXT ||
+			   registered_fb[con2fb_map[i]] != info)
+			continue;
+
+		if (vc->vc_font.width  > FBCON_SWAP(var->rotate, var->xres, var->yres) ||
+		    vc->vc_font.height > FBCON_SWAP(var->rotate, var->yres, var->xres))
+			return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fbcon_modechange_possible);
+
 int fbcon_mode_deleted(struct fb_info *info,
 		       struct fb_videomode *mode)
 {
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index a6bb0e438216..85de02d0d3aa 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -510,7 +510,7 @@ static int fb_show_logo_line(struct fb_info *info, int rotate,
 
 		while (n && (n * (logo->width + 8) - 8 > xres))
 			--n;
-		image.dx = (xres - n * (logo->width + 8) - 8) / 2;
+		image.dx = (xres - (n * (logo->width + 8) - 8)) / 2;
 		image.dy = y ?: (yres - logo->height) / 2;
 	} else {
 		image.dx = 0;
@@ -1016,6 +1016,16 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
 	if (ret)
 		return ret;
 
+	/* verify that virtual resolution >= physical resolution */
+	if (var->xres_virtual < var->xres ||
+	    var->yres_virtual < var->yres) {
+		pr_warn("WARNING: fbcon: Driver '%s' missed to adjust virtual screen size (%ux%u vs. %ux%u)\n",
+			info->fix.id,
+			var->xres_virtual, var->yres_virtual,
+			var->xres, var->yres);
+		return -EINVAL;
+	}
+
 	if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
 		return 0;
 
@@ -1106,7 +1116,9 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
 			return -EFAULT;
 		console_lock();
 		lock_fb_info(info);
-		ret = fb_set_var(info, &var);
+		ret = fbcon_modechange_possible(info, &var);
+		if (!ret)
+			ret = fb_set_var(info, &var);
 		if (!ret)
 			fbcon_update_vcs(info, var.activate & FB_ACTIVATE_ALL);
 		unlock_fb_info(info);
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index 9d3cf0111709..7c3726aa9e14 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -517,7 +517,14 @@ static void fscache_perform_lookup(struct fscache_cookie *cookie)
 	}
 
 	fscache_see_cookie(cookie, fscache_cookie_see_active);
-	fscache_set_cookie_state(cookie, FSCACHE_COOKIE_STATE_ACTIVE);
+	spin_lock(&cookie->lock);
+	if (test_and_clear_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags))
+		__fscache_set_cookie_state(cookie,
+					   FSCACHE_COOKIE_STATE_INVALIDATING);
+	else
+		__fscache_set_cookie_state(cookie, FSCACHE_COOKIE_STATE_ACTIVE);
+	spin_unlock(&cookie->lock);
+	wake_up_cookie_state(cookie);
 	trace = fscache_access_lookup_cookie_end;
 
 out:
@@ -752,6 +759,9 @@ static void fscache_cookie_state_machine(struct fscache_cookie *cookie)
 			spin_lock(&cookie->lock);
 		}
 
+		if (test_and_clear_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags))
+			fscache_end_cookie_access(cookie, fscache_access_invalidate_cookie_end);
+
 		switch (state) {
 		case FSCACHE_COOKIE_STATE_RELINQUISHING:
 			fscache_see_cookie(cookie, fscache_cookie_see_relinquish);
@@ -1048,6 +1058,9 @@ void __fscache_invalidate(struct fscache_cookie *cookie,
 		return;
 
 	case FSCACHE_COOKIE_STATE_LOOKING_UP:
+		__fscache_begin_cookie_access(cookie, fscache_access_invalidate_cookie);
+		set_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags);
+		fallthrough;
 	case FSCACHE_COOKIE_STATE_CREATING:
 		spin_unlock(&cookie->lock);
 		_leave(" [look %x]", cookie->inval_counter);
diff --git a/fs/fscache/volume.c b/fs/fscache/volume.c
index f2aa7dbad766..a058e0136bfe 100644
--- a/fs/fscache/volume.c
+++ b/fs/fscache/volume.c
@@ -143,7 +143,7 @@ static void fscache_wait_on_volume_collision(struct fscache_volume *candidate,
 {
 	wait_var_event_timeout(&candidate->flags,
 			       !fscache_is_acquire_pending(candidate), 20 * HZ);
-	if (!fscache_is_acquire_pending(candidate)) {
+	if (fscache_is_acquire_pending(candidate)) {
 		pr_notice("Potential volume collision new=%08x old=%08x",
 			  candidate->debug_id, collidee_debug_id);
 		fscache_stat(&fscache_n_volumes_collision);
@@ -182,7 +182,7 @@ static bool fscache_hash_volume(struct fscache_volume *candidate)
 	hlist_bl_add_head(&candidate->hash_link, h);
 	hlist_bl_unlock(h);
 
-	if (test_bit(FSCACHE_VOLUME_ACQUIRE_PENDING, &candidate->flags))
+	if (fscache_is_acquire_pending(candidate))
 		fscache_wait_on_volume_collision(candidate, collidee_debug_id);
 	return true;
 
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 7e8c715052c0..3d97372e811e 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -3495,6 +3495,13 @@ static ssize_t io_iov_buffer_select(struct io_kiocb *req, struct iovec *iov,
 	return __io_iov_buffer_select(req, iov, issue_flags);
 }
 
+static inline bool io_do_buffer_select(struct io_kiocb *req)
+{
+	if (!(req->flags & REQ_F_BUFFER_SELECT))
+		return false;
+	return !(req->flags & REQ_F_BUFFER_SELECTED);
+}
+
 static struct iovec *__io_import_iovec(int rw, struct io_kiocb *req,
 				       struct io_rw_state *s,
 				       unsigned int issue_flags)
@@ -3854,18 +3861,19 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags)
 		if (unlikely(ret < 0))
 			return ret;
 	} else {
+		rw = req->async_data;
+		s = &rw->s;
+
 		/*
 		 * Safe and required to re-import if we're using provided
 		 * buffers, as we dropped the selected one before retry.
 		 */
-		if (req->flags & REQ_F_BUFFER_SELECT) {
+		if (io_do_buffer_select(req)) {
 			ret = io_import_iovec(READ, req, &iovec, s, issue_flags);
 			if (unlikely(ret < 0))
 				return ret;
 		}
 
-		rw = req->async_data;
-		s = &rw->s;
 		/*
 		 * We come here from an earlier attempt, restore our state to
 		 * match in case it doesn't. It's cheap enough that we don't
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
index 92b7ea8d8f5e..181907349b49 100644
--- a/include/acpi/cppc_acpi.h
+++ b/include/acpi/cppc_acpi.h
@@ -144,6 +144,7 @@ extern bool acpi_cpc_valid(void);
 extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
 extern unsigned int cppc_get_transition_latency(int cpu);
 extern bool cpc_ffh_supported(void);
+extern bool cpc_supported_by_cpu(void);
 extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val);
 extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val);
 #else /* !CONFIG_ACPI_CPPC_LIB */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d7136d13aa44..cf1f770208da 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -574,13 +574,15 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
 #define OSC_SB_OSLPI_SUPPORT			0x00000100
 #define OSC_SB_CPC_DIVERSE_HIGH_SUPPORT		0x00001000
 #define OSC_SB_GENERIC_INITIATOR_SUPPORT	0x00002000
+#define OSC_SB_CPC_FLEXIBLE_ADR_SPACE		0x00004000
 #define OSC_SB_NATIVE_USB4_SUPPORT		0x00040000
 #define OSC_SB_PRM_SUPPORT			0x00200000
 
 extern bool osc_sb_apei_support_acked;
 extern bool osc_pc_lpi_support_confirmed;
 extern bool osc_sb_native_usb4_support_confirmed;
-extern bool osc_sb_cppc_not_supported;
+extern bool osc_sb_cppc2_support_acked;
+extern bool osc_cpc_flexible_adr_space_confirmed;
 
 /* USB4 Capabilities */
 #define OSC_USB_USB3_TUNNELING			0x00000001
diff --git a/include/linux/fbcon.h b/include/linux/fbcon.h
index ff5596dd30f8..2382dec6d6ab 100644
--- a/include/linux/fbcon.h
+++ b/include/linux/fbcon.h
@@ -15,6 +15,8 @@ void fbcon_new_modelist(struct fb_info *info);
 void fbcon_get_requirement(struct fb_info *info,
 			   struct fb_blit_caps *caps);
 void fbcon_fb_blanked(struct fb_info *info, int blank);
+int  fbcon_modechange_possible(struct fb_info *info,
+			       struct fb_var_screeninfo *var);
 void fbcon_update_vcs(struct fb_info *info, bool all);
 void fbcon_remap_all(struct fb_info *info);
 int fbcon_set_con2fb_map_ioctl(void __user *argp);
@@ -33,6 +35,8 @@ static inline void fbcon_new_modelist(struct fb_info *info) {}
 static inline void fbcon_get_requirement(struct fb_info *info,
 					 struct fb_blit_caps *caps) {}
 static inline void fbcon_fb_blanked(struct fb_info *info, int blank) {}
+static inline int  fbcon_modechange_possible(struct fb_info *info,
+				struct fb_var_screeninfo *var) { return 0; }
 static inline void fbcon_update_vcs(struct fb_info *info, bool all) {}
 static inline void fbcon_remap_all(struct fb_info *info) {}
 static inline int fbcon_set_con2fb_map_ioctl(void __user *argp) { return 0; }
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index e25539072463..a25804f141d3 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -129,6 +129,7 @@ struct fscache_cookie {
 #define FSCACHE_COOKIE_DO_PREP_TO_WRITE	12		/* T if cookie needs write preparation */
 #define FSCACHE_COOKIE_HAVE_DATA	13		/* T if this cookie has data stored */
 #define FSCACHE_COOKIE_IS_HASHED	14		/* T if this cookie is hashed */
+#define FSCACHE_COOKIE_DO_INVALIDATE	15		/* T if cookie needs invalidation */
 
 	enum fscache_cookie_state	state;
 	u8				advice;		/* FSCACHE_ADV_* */
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 2f9891cb3d00..82543019ff01 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -611,7 +611,6 @@ struct intel_iommu {
 struct device_domain_info {
 	struct list_head link;	/* link to domain siblings */
 	struct list_head global; /* link to global list */
-	struct list_head table;	/* link to pasid table */
 	u32 segment;		/* PCI segment number */
 	u8 bus;			/* PCI bus number */
 	u8 devfn;		/* PCI devfn number */
@@ -728,8 +727,6 @@ extern int dmar_ir_support(void);
 void *alloc_pgtable_page(int node);
 void free_pgtable_page(void *vaddr);
 struct intel_iommu *domain_get_iommu(struct dmar_domain *domain);
-int for_each_device_domain(int (*fn)(struct device_domain_info *info,
-				     void *data), void *data);
 void iommu_flush_write_buffer(struct intel_iommu *iommu);
 int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev);
 struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn);
diff --git a/include/linux/memregion.h b/include/linux/memregion.h
index e11595256cac..c04c4fd2e209 100644
--- a/include/linux/memregion.h
+++ b/include/linux/memregion.h
@@ -16,7 +16,7 @@ static inline int memregion_alloc(gfp_t gfp)
 {
 	return -ENOMEM;
 }
-void memregion_free(int id)
+static inline void memregion_free(int id)
 {
 }
 #endif
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index 2bff6a10095d..73634b6653a1 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -82,7 +82,7 @@ extern void pm_runtime_get_suppliers(struct device *dev);
 extern void pm_runtime_put_suppliers(struct device *dev);
 extern void pm_runtime_new_link(struct device *dev);
 extern void pm_runtime_drop_link(struct device_link *link);
-extern void pm_runtime_release_supplier(struct device_link *link, bool check_idle);
+extern void pm_runtime_release_supplier(struct device_link *link);
 
 extern int devm_pm_runtime_enable(struct device *dev);
 
@@ -308,8 +308,7 @@ static inline void pm_runtime_get_suppliers(struct device *dev) {}
 static inline void pm_runtime_put_suppliers(struct device *dev) {}
 static inline void pm_runtime_new_link(struct device *dev) {}
 static inline void pm_runtime_drop_link(struct device_link *link) {}
-static inline void pm_runtime_release_supplier(struct device_link *link,
-					       bool check_idle) {}
+static inline void pm_runtime_release_supplier(struct device_link *link) {}
 
 #endif /* !CONFIG_PM */
 
diff --git a/include/linux/rtsx_usb.h b/include/linux/rtsx_usb.h
index 159729cffd8e..3247ed8e9ff0 100644
--- a/include/linux/rtsx_usb.h
+++ b/include/linux/rtsx_usb.h
@@ -54,8 +54,6 @@ struct rtsx_ucr {
 	struct usb_device	*pusb_dev;
 	struct usb_interface	*pusb_intf;
 	struct usb_sg_request	current_sg;
-	unsigned char		*iobuf;
-	dma_addr_t		iobuf_dma;
 
 	struct timer_list	sg_timer;
 	struct mutex		dev_mutex;
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 3049cb69c025..9cf6870b526e 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -134,7 +134,8 @@ struct tc_action_ops {
 	(*get_psample_group)(const struct tc_action *a,
 			     tc_action_priv_destructor *destructor);
 	int     (*offload_act_setup)(struct tc_action *act, void *entry_data,
-				     u32 *index_inc, bool bind);
+				     u32 *index_inc, bool bind,
+				     struct netlink_ext_ack *extack);
 };
 
 struct tc_action_net {
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index 6484095a8c01..7ac313858037 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -152,6 +152,7 @@ enum flow_action_id {
 	FLOW_ACTION_PIPE,
 	FLOW_ACTION_VLAN_PUSH_ETH,
 	FLOW_ACTION_VLAN_POP_ETH,
+	FLOW_ACTION_CONTINUE,
 	NUM_FLOW_ACTIONS,
 };
 
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index a3b57a93228a..8cf001aed858 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -547,10 +547,12 @@ tcf_match_indev(struct sk_buff *skb, int ifindex)
 }
 
 int tc_setup_offload_action(struct flow_action *flow_action,
-			    const struct tcf_exts *exts);
+			    const struct tcf_exts *exts,
+			    struct netlink_ext_ack *extack);
 void tc_cleanup_offload_action(struct flow_action *flow_action);
 int tc_setup_action(struct flow_action *flow_action,
-		    struct tc_action *actions[]);
+		    struct tc_action *actions[],
+		    struct netlink_ext_ack *extack);
 
 int tc_setup_cb_call(struct tcf_block *block, enum tc_setup_type type,
 		     void *type_data, bool err_stop, bool rtnl_held);
diff --git a/include/video/of_display_timing.h b/include/video/of_display_timing.h
index e1126a74882a..eff166fdd81b 100644
--- a/include/video/of_display_timing.h
+++ b/include/video/of_display_timing.h
@@ -8,6 +8,8 @@
 #ifndef __LINUX_OF_DISPLAY_TIMING_H
 #define __LINUX_OF_DISPLAY_TIMING_H
 
+#include <linux/errno.h>
+
 struct device_node;
 struct display_timing;
 struct display_timings;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 9c1a02b82ecd..d04147a5efa5 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1417,6 +1417,21 @@ static void __reg_bound_offset(struct bpf_reg_state *reg)
 	reg->var_off = tnum_or(tnum_clear_subreg(var64_off), var32_off);
 }
 
+static void reg_bounds_sync(struct bpf_reg_state *reg)
+{
+	/* We might have learned new bounds from the var_off. */
+	__update_reg_bounds(reg);
+	/* We might have learned something about the sign bit. */
+	__reg_deduce_bounds(reg);
+	/* We might have learned some bits from the bounds. */
+	__reg_bound_offset(reg);
+	/* Intersecting with the old var_off might have improved our bounds
+	 * slightly, e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc),
+	 * then new var_off is (0; 0x7f...fc) which improves our umax.
+	 */
+	__update_reg_bounds(reg);
+}
+
 static bool __reg32_bound_s64(s32 a)
 {
 	return a >= 0 && a <= S32_MAX;
@@ -1458,16 +1473,8 @@ static void __reg_combine_32_into_64(struct bpf_reg_state *reg)
 		 * so they do not impact tnum bounds calculation.
 		 */
 		__mark_reg64_unbounded(reg);
-		__update_reg_bounds(reg);
 	}
-
-	/* Intersecting with the old var_off might have improved our bounds
-	 * slightly.  e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc),
-	 * then new var_off is (0; 0x7f...fc) which improves our umax.
-	 */
-	__reg_deduce_bounds(reg);
-	__reg_bound_offset(reg);
-	__update_reg_bounds(reg);
+	reg_bounds_sync(reg);
 }
 
 static bool __reg64_bound_s32(s64 a)
@@ -1483,7 +1490,6 @@ static bool __reg64_bound_u32(u64 a)
 static void __reg_combine_64_into_32(struct bpf_reg_state *reg)
 {
 	__mark_reg32_unbounded(reg);
-
 	if (__reg64_bound_s32(reg->smin_value) && __reg64_bound_s32(reg->smax_value)) {
 		reg->s32_min_value = (s32)reg->smin_value;
 		reg->s32_max_value = (s32)reg->smax_value;
@@ -1492,14 +1498,7 @@ static void __reg_combine_64_into_32(struct bpf_reg_state *reg)
 		reg->u32_min_value = (u32)reg->umin_value;
 		reg->u32_max_value = (u32)reg->umax_value;
 	}
-
-	/* Intersecting with the old var_off might have improved our bounds
-	 * slightly.  e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc),
-	 * then new var_off is (0; 0x7f...fc) which improves our umax.
-	 */
-	__reg_deduce_bounds(reg);
-	__reg_bound_offset(reg);
-	__update_reg_bounds(reg);
+	reg_bounds_sync(reg);
 }
 
 /* Mark a register as having a completely unknown (scalar) value. */
@@ -6485,9 +6484,7 @@ static void do_refine_retval_range(struct bpf_reg_state *regs, int ret_type,
 	ret_reg->s32_max_value = meta->msize_max_value;
 	ret_reg->smin_value = -MAX_ERRNO;
 	ret_reg->s32_min_value = -MAX_ERRNO;
-	__reg_deduce_bounds(ret_reg);
-	__reg_bound_offset(ret_reg);
-	__update_reg_bounds(ret_reg);
+	reg_bounds_sync(ret_reg);
 }
 
 static int
@@ -7693,11 +7690,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
 
 	if (!check_reg_sane_offset(env, dst_reg, ptr_reg->type))
 		return -EINVAL;
-
-	__update_reg_bounds(dst_reg);
-	__reg_deduce_bounds(dst_reg);
-	__reg_bound_offset(dst_reg);
-
+	reg_bounds_sync(dst_reg);
 	if (sanitize_check_bounds(env, insn, dst_reg) < 0)
 		return -EACCES;
 	if (sanitize_needed(opcode)) {
@@ -8435,10 +8428,7 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
 	/* ALU32 ops are zero extended into 64bit register */
 	if (alu32)
 		zext_32_to_64(dst_reg);
-
-	__update_reg_bounds(dst_reg);
-	__reg_deduce_bounds(dst_reg);
-	__reg_bound_offset(dst_reg);
+	reg_bounds_sync(dst_reg);
 	return 0;
 }
 
@@ -8627,10 +8617,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
 							 insn->dst_reg);
 				}
 				zext_32_to_64(dst_reg);
-
-				__update_reg_bounds(dst_reg);
-				__reg_deduce_bounds(dst_reg);
-				__reg_bound_offset(dst_reg);
+				reg_bounds_sync(dst_reg);
 			}
 		} else {
 			/* case: R = imm
@@ -9068,26 +9055,33 @@ static void reg_set_min_max(struct bpf_reg_state *true_reg,
 		return;
 
 	switch (opcode) {
+	/* JEQ/JNE comparison doesn't change the register equivalence.
+	 *
+	 * r1 = r2;
+	 * if (r1 == 42) goto label;
+	 * ...
+	 * label: // here both r1 and r2 are known to be 42.
+	 *
+	 * Hence when marking register as known preserve it's ID.
+	 */
 	case BPF_JEQ:
+		if (is_jmp32) {
+			__mark_reg32_known(true_reg, val32);
+			true_32off = tnum_subreg(true_reg->var_off);
+		} else {
+			___mark_reg_known(true_reg, val);
+			true_64off = true_reg->var_off;
+		}
+		break;
 	case BPF_JNE:
-	{
-		struct bpf_reg_state *reg =
-			opcode == BPF_JEQ ? true_reg : false_reg;
-
-		/* JEQ/JNE comparison doesn't change the register equivalence.
-		 * r1 = r2;
-		 * if (r1 == 42) goto label;
-		 * ...
-		 * label: // here both r1 and r2 are known to be 42.
-		 *
-		 * Hence when marking register as known preserve it's ID.
-		 */
-		if (is_jmp32)
-			__mark_reg32_known(reg, val32);
-		else
-			___mark_reg_known(reg, val);
+		if (is_jmp32) {
+			__mark_reg32_known(false_reg, val32);
+			false_32off = tnum_subreg(false_reg->var_off);
+		} else {
+			___mark_reg_known(false_reg, val);
+			false_64off = false_reg->var_off;
+		}
 		break;
-	}
 	case BPF_JSET:
 		if (is_jmp32) {
 			false_32off = tnum_and(false_32off, tnum_const(~val32));
@@ -9226,21 +9220,8 @@ static void __reg_combine_min_max(struct bpf_reg_state *src_reg,
 							dst_reg->smax_value);
 	src_reg->var_off = dst_reg->var_off = tnum_intersect(src_reg->var_off,
 							     dst_reg->var_off);
-	/* We might have learned new bounds from the var_off. */
-	__update_reg_bounds(src_reg);
-	__update_reg_bounds(dst_reg);
-	/* We might have learned something about the sign bit. */
-	__reg_deduce_bounds(src_reg);
-	__reg_deduce_bounds(dst_reg);
-	/* We might have learned some bits from the bounds. */
-	__reg_bound_offset(src_reg);
-	__reg_bound_offset(dst_reg);
-	/* Intersecting with the old var_off might have improved our bounds
-	 * slightly.  e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc),
-	 * then new var_off is (0; 0x7f...fc) which improves our umax.
-	 */
-	__update_reg_bounds(src_reg);
-	__update_reg_bounds(dst_reg);
+	reg_bounds_sync(src_reg);
+	reg_bounds_sync(dst_reg);
 }
 
 static void reg_combine_min_max(struct bpf_reg_state *true_src,
diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
index 6833d8887181..d30e4db04506 100644
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -382,9 +382,11 @@ void cleanup_srcu_struct(struct srcu_struct *ssp)
 			return; /* Forgot srcu_barrier(), so just leak it! */
 	}
 	if (WARN_ON(rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)) != SRCU_STATE_IDLE) ||
+	    WARN_ON(rcu_seq_current(&ssp->srcu_gp_seq) != ssp->srcu_gp_seq_needed) ||
 	    WARN_ON(srcu_readers_active(ssp))) {
-		pr_info("%s: Active srcu_struct %p state: %d\n",
-			__func__, ssp, rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)));
+		pr_info("%s: Active srcu_struct %p read state: %d gp state: %lu/%lu\n",
+			__func__, ssp, rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)),
+			rcu_seq_current(&ssp->srcu_gp_seq), ssp->srcu_gp_seq_needed);
 		return; /* Caller forgot to stop doing call_srcu()? */
 	}
 	free_percpu(ssp->sda);
diff --git a/lib/idr.c b/lib/idr.c
index f4ab4f4aa3c7..7ecdfdb5309e 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -491,7 +491,8 @@ void ida_free(struct ida *ida, unsigned int id)
 	struct ida_bitmap *bitmap;
 	unsigned long flags;
 
-	BUG_ON((int)id < 0);
+	if ((int)id < 0)
+		return;
 
 	xas_lock_irqsave(&xas, flags);
 	bitmap = xas_load(&xas);
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 64c07e650bb4..c3ad310c2109 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -100,6 +100,7 @@ static inline u64 get_u64(const struct canfd_frame *cp, int offset)
 
 struct bcm_op {
 	struct list_head list;
+	struct rcu_head rcu;
 	int ifindex;
 	canid_t can_id;
 	u32 flags;
@@ -718,10 +719,9 @@ static struct bcm_op *bcm_find_op(struct list_head *ops,
 	return NULL;
 }
 
-static void bcm_remove_op(struct bcm_op *op)
+static void bcm_free_op_rcu(struct rcu_head *rcu_head)
 {
-	hrtimer_cancel(&op->timer);
-	hrtimer_cancel(&op->thrtimer);
+	struct bcm_op *op = container_of(rcu_head, struct bcm_op, rcu);
 
 	if ((op->frames) && (op->frames != &op->sframe))
 		kfree(op->frames);
@@ -732,6 +732,14 @@ static void bcm_remove_op(struct bcm_op *op)
 	kfree(op);
 }
 
+static void bcm_remove_op(struct bcm_op *op)
+{
+	hrtimer_cancel(&op->timer);
+	hrtimer_cancel(&op->thrtimer);
+
+	call_rcu(&op->rcu, bcm_free_op_rcu);
+}
+
 static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op)
 {
 	if (op->rx_reg_dev == dev) {
@@ -757,6 +765,9 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
 		if ((op->can_id == mh->can_id) && (op->ifindex == ifindex) &&
 		    (op->flags & CAN_FD_FRAME) == (mh->flags & CAN_FD_FRAME)) {
 
+			/* disable automatic timer on frame reception */
+			op->flags |= RX_NO_AUTOTIMER;
+
 			/*
 			 * Don't care if we're bound or not (due to netdev
 			 * problems) can_rx_unregister() is always a save
@@ -785,7 +796,6 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
 						  bcm_rx_handler, op);
 
 			list_del(&op->list);
-			synchronize_rcu();
 			bcm_remove_op(op);
 			return 1; /* done */
 		}
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index b548cec86c9d..48e34b81fa1c 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -1538,6 +1538,9 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
 		*ptr++ = mptcp_option(MPTCPOPT_MP_PRIO,
 				      TCPOLEN_MPTCP_PRIO,
 				      opts->backup, TCPOPT_NOP);
+
+		MPTCP_INC_STATS(sock_net((const struct sock *)tp),
+				MPTCP_MIB_MPPRIOTX);
 	}
 
 mp_capable_done:
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index e3dcc5501579..78345278e4a7 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -720,24 +720,23 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
 
 	mptcp_for_each_subflow(msk, subflow) {
 		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
-		struct sock *sk = (struct sock *)msk;
 		struct mptcp_addr_info local;
+		bool slow;
 
 		local_address((struct sock_common *)ssk, &local);
 		if (!addresses_equal(&local, addr, addr->port))
 			continue;
 
+		slow = lock_sock_fast(ssk);
 		if (subflow->backup != bkup)
 			msk->last_snd = NULL;
 		subflow->backup = bkup;
 		subflow->send_mp_prio = 1;
 		subflow->request_bkup = bkup;
-		__MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPPRIOTX);
 
-		spin_unlock_bh(&msk->pm.lock);
 		pr_debug("send ack for mp_prio");
-		mptcp_subflow_send_ack(ssk);
-		spin_lock_bh(&msk->pm.lock);
+		__mptcp_subflow_send_ack(ssk);
+		unlock_sock_fast(ssk, slow);
 
 		return 0;
 	}
@@ -794,7 +793,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
 			removed = true;
 			__MPTCP_INC_STATS(sock_net(sk), rm_type);
 		}
-		__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
+		if (rm_type == MPTCP_MIB_RMSUBFLOW)
+			__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
 		if (!removed)
 			continue;
 
@@ -1769,8 +1769,10 @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,
 
 	list.ids[list.nr++] = addr->id;
 
+	spin_lock_bh(&msk->pm.lock);
 	mptcp_pm_nl_rm_subflow_received(msk, &list);
 	mptcp_pm_create_subflow_or_signal_addr(msk);
+	spin_unlock_bh(&msk->pm.lock);
 }
 
 static int mptcp_nl_set_flags(struct net *net,
@@ -1788,12 +1790,10 @@ static int mptcp_nl_set_flags(struct net *net,
 			goto next;
 
 		lock_sock(sk);
-		spin_lock_bh(&msk->pm.lock);
 		if (changed & MPTCP_PM_ADDR_FLAG_BACKUP)
 			ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, bkup);
 		if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)
 			mptcp_pm_nl_fullmesh(msk, addr);
-		spin_unlock_bh(&msk->pm.lock);
 		release_sock(sk);
 
 next:
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 713077eef04a..b0fb1fc0bd4a 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -506,13 +506,18 @@ static bool tcp_can_send_ack(const struct sock *ssk)
 	       (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_TIME_WAIT | TCPF_CLOSE | TCPF_LISTEN));
 }
 
+void __mptcp_subflow_send_ack(struct sock *ssk)
+{
+	if (tcp_can_send_ack(ssk))
+		tcp_send_ack(ssk);
+}
+
 void mptcp_subflow_send_ack(struct sock *ssk)
 {
 	bool slow;
 
 	slow = lock_sock_fast(ssk);
-	if (tcp_can_send_ack(ssk))
-		tcp_send_ack(ssk);
+	__mptcp_subflow_send_ack(ssk);
 	unlock_sock_fast(ssk, slow);
 }
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 2aab5aff6bcd..ad36a05aa67d 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -584,6 +584,7 @@ void __init mptcp_subflow_init(void);
 void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
 void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
 		     struct mptcp_subflow_context *subflow);
+void __mptcp_subflow_send_ack(struct sock *ssk);
 void mptcp_subflow_send_ack(struct sock *ssk);
 void mptcp_subflow_reset(struct sock *ssk);
 void mptcp_subflow_queue_clean(struct sock *ssk);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 81243c834abb..a136148627e7 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5213,13 +5213,20 @@ static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set,
 				  struct nft_data *data,
 				  struct nlattr *attr)
 {
+	u32 dtype;
 	int err;
 
 	err = nft_data_init(ctx, data, NFT_DATA_VALUE_MAXLEN, desc, attr);
 	if (err < 0)
 		return err;
 
-	if (desc->type != NFT_DATA_VERDICT && desc->len != set->dlen) {
+	if (set->dtype == NFT_DATA_VERDICT)
+		dtype = NFT_DATA_VERDICT;
+	else
+		dtype = NFT_DATA_VALUE;
+
+	if (dtype != desc->type ||
+	    set->dlen != desc->len) {
 		nft_data_release(data, desc->type);
 		return -EINVAL;
 	}
diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
index 2c8051d8cca6..4f9299b9dcdd 100644
--- a/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -2124,6 +2124,32 @@ static int nft_pipapo_init(const struct nft_set *set,
 	return err;
 }
 
+/**
+ * nft_set_pipapo_match_destroy() - Destroy elements from key mapping array
+ * @set:	nftables API set representation
+ * @m:		matching data pointing to key mapping array
+ */
+static void nft_set_pipapo_match_destroy(const struct nft_set *set,
+					 struct nft_pipapo_match *m)
+{
+	struct nft_pipapo_field *f;
+	int i, r;
+
+	for (i = 0, f = m->f; i < m->field_count - 1; i++, f++)
+		;
+
+	for (r = 0; r < f->rules; r++) {
+		struct nft_pipapo_elem *e;
+
+		if (r < f->rules - 1 && f->mt[r + 1].e == f->mt[r].e)
+			continue;
+
+		e = f->mt[r].e;
+
+		nft_set_elem_destroy(set, e, true);
+	}
+}
+
 /**
  * nft_pipapo_destroy() - Free private data for set and all committed elements
  * @set:	nftables API set representation
@@ -2132,26 +2158,13 @@ static void nft_pipapo_destroy(const struct nft_set *set)
 {
 	struct nft_pipapo *priv = nft_set_priv(set);
 	struct nft_pipapo_match *m;
-	struct nft_pipapo_field *f;
-	int i, r, cpu;
+	int cpu;
 
 	m = rcu_dereference_protected(priv->match, true);
 	if (m) {
 		rcu_barrier();
 
-		for (i = 0, f = m->f; i < m->field_count - 1; i++, f++)
-			;
-
-		for (r = 0; r < f->rules; r++) {
-			struct nft_pipapo_elem *e;
-
-			if (r < f->rules - 1 && f->mt[r + 1].e == f->mt[r].e)
-				continue;
-
-			e = f->mt[r].e;
-
-			nft_set_elem_destroy(set, e, true);
-		}
+		nft_set_pipapo_match_destroy(set, m);
 
 #ifdef NFT_PIPAPO_ALIGN
 		free_percpu(m->scratch_aligned);
@@ -2165,6 +2178,11 @@ static void nft_pipapo_destroy(const struct nft_set *set)
 	}
 
 	if (priv->clone) {
+		m = priv->clone;
+
+		if (priv->dirty)
+			nft_set_pipapo_match_destroy(set, m);
+
 #ifdef NFT_PIPAPO_ALIGN
 		free_percpu(priv->clone->scratch_aligned);
 #endif
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index e2e6b6b78578..5e93510fa3d2 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -227,8 +227,8 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
 {
 	struct rose_neigh *s;
 
-	rose_stop_ftimer(rose_neigh);
-	rose_stop_t0timer(rose_neigh);
+	del_timer_sync(&rose_neigh->ftimer);
+	del_timer_sync(&rose_neigh->t0timer);
 
 	skb_queue_purge(&rose_neigh->queue);
 
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 6fa9e7b1406a..817065aa2833 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -195,7 +195,7 @@ static int offload_action_init(struct flow_offload_action *fl_action,
 	if (act->ops->offload_act_setup) {
 		spin_lock_bh(&act->tcfa_lock);
 		err = act->ops->offload_act_setup(act, fl_action, NULL,
-						  false);
+						  false, extack);
 		spin_unlock_bh(&act->tcfa_lock);
 		return err;
 	}
@@ -271,7 +271,7 @@ static int tcf_action_offload_add_ex(struct tc_action *action,
 	if (err)
 		goto fl_err;
 
-	err = tc_setup_action(&fl_action->action, actions);
+	err = tc_setup_action(&fl_action->action, actions, extack);
 	if (err) {
 		NL_SET_ERR_MSG_MOD(extack,
 				   "Failed to setup tc actions for offload");
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
index e0f515b774ca..22847ee009ef 100644
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@ -696,7 +696,8 @@ static size_t tcf_csum_get_fill_size(const struct tc_action *act)
 }
 
 static int tcf_csum_offload_act_setup(struct tc_action *act, void *entry_data,
-				      u32 *index_inc, bool bind)
+				      u32 *index_inc, bool bind,
+				      struct netlink_ext_ack *extack)
 {
 	if (bind) {
 		struct flow_action_entry *entry = entry_data;
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index b3ca837fd4e8..e013253b10d1 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -1584,7 +1584,8 @@ static void tcf_stats_update(struct tc_action *a, u64 bytes, u64 packets,
 }
 
 static int tcf_ct_offload_act_setup(struct tc_action *act, void *entry_data,
-				    u32 *index_inc, bool bind)
+				    u32 *index_inc, bool bind,
+				    struct netlink_ext_ack *extack)
 {
 	if (bind) {
 		struct flow_action_entry *entry = entry_data;
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index bde6a6c01e64..db84a0473cc1 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -253,7 +253,8 @@ static size_t tcf_gact_get_fill_size(const struct tc_action *act)
 }
 
 static int tcf_gact_offload_act_setup(struct tc_action *act, void *entry_data,
-				      u32 *index_inc, bool bind)
+				      u32 *index_inc, bool bind,
+				      struct netlink_ext_ack *extack)
 {
 	if (bind) {
 		struct flow_action_entry *entry = entry_data;
diff --git a/net/sched/act_gate.c b/net/sched/act_gate.c
index d56e73843a4b..fd5155274733 100644
--- a/net/sched/act_gate.c
+++ b/net/sched/act_gate.c
@@ -619,7 +619,8 @@ static int tcf_gate_get_entries(struct flow_action_entry *entry,
 }
 
 static int tcf_gate_offload_act_setup(struct tc_action *act, void *entry_data,
-				      u32 *index_inc, bool bind)
+				      u32 *index_inc, bool bind,
+				      struct netlink_ext_ack *extack)
 {
 	int err;
 
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 39acd1d18609..70a6a4447e6b 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -460,7 +460,8 @@ static void tcf_offload_mirred_get_dev(struct flow_action_entry *entry,
 }
 
 static int tcf_mirred_offload_act_setup(struct tc_action *act, void *entry_data,
-					u32 *index_inc, bool bind)
+					u32 *index_inc, bool bind,
+					struct netlink_ext_ack *extack)
 {
 	if (bind) {
 		struct flow_action_entry *entry = entry_data;
diff --git a/net/sched/act_mpls.c b/net/sched/act_mpls.c
index b9ff3459fdab..23fcfa5605df 100644
--- a/net/sched/act_mpls.c
+++ b/net/sched/act_mpls.c
@@ -385,7 +385,8 @@ static int tcf_mpls_search(struct net *net, struct tc_action **a, u32 index)
 }
 
 static int tcf_mpls_offload_act_setup(struct tc_action *act, void *entry_data,
-				      u32 *index_inc, bool bind)
+				      u32 *index_inc, bool bind,
+				      struct netlink_ext_ack *extack)
 {
 	if (bind) {
 		struct flow_action_entry *entry = entry_data;
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 211c757bfc3c..8fccc914f464 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -510,7 +510,8 @@ static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index)
 }
 
 static int tcf_pedit_offload_act_setup(struct tc_action *act, void *entry_data,
-				       u32 *index_inc, bool bind)
+				       u32 *index_inc, bool bind,
+				       struct netlink_ext_ack *extack)
 {
 	if (bind) {
 		struct flow_action_entry *entry = entry_data;
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index f4d917705263..b759628a47c2 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -419,7 +419,8 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index)
 	return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_police_act_to_flow_act(int tc_act, u32 *extval)
+static int tcf_police_act_to_flow_act(int tc_act, u32 *extval,
+				      struct netlink_ext_ack *extack)
 {
 	int act_id = -EOPNOTSUPP;
 
@@ -430,19 +431,28 @@ static int tcf_police_act_to_flow_act(int tc_act, u32 *extval)
 			act_id = FLOW_ACTION_DROP;
 		else if (tc_act == TC_ACT_PIPE)
 			act_id = FLOW_ACTION_PIPE;
+		else if (tc_act == TC_ACT_RECLASSIFY)
+			NL_SET_ERR_MSG_MOD(extack, "Offload not supported when conform/exceed action is \"reclassify\"");
+		else
+			NL_SET_ERR_MSG_MOD(extack, "Unsupported conform/exceed action offload");
 	} else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_GOTO_CHAIN)) {
 		act_id = FLOW_ACTION_GOTO;
 		*extval = tc_act & TC_ACT_EXT_VAL_MASK;
 	} else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_JUMP)) {
 		act_id = FLOW_ACTION_JUMP;
 		*extval = tc_act & TC_ACT_EXT_VAL_MASK;
+	} else if (tc_act == TC_ACT_UNSPEC) {
+		act_id = FLOW_ACTION_CONTINUE;
+	} else {
+		NL_SET_ERR_MSG_MOD(extack, "Unsupported conform/exceed action offload");
 	}
 
 	return act_id;
 }
 
 static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,
-					u32 *index_inc, bool bind)
+					u32 *index_inc, bool bind,
+					struct netlink_ext_ack *extack)
 {
 	if (bind) {
 		struct flow_action_entry *entry = entry_data;
@@ -466,14 +476,16 @@ static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,
 		entry->police.mtu = tcf_police_tcfp_mtu(act);
 
 		act_id = tcf_police_act_to_flow_act(police->tcf_action,
-						    &entry->police.exceed.extval);
+						    &entry->police.exceed.extval,
+						    extack);
 		if (act_id < 0)
 			return act_id;
 
 		entry->police.exceed.act_id = act_id;
 
 		act_id = tcf_police_act_to_flow_act(p->tcfp_result,
-						    &entry->police.notexceed.extval);
+						    &entry->police.notexceed.extval,
+						    extack);
 		if (act_id < 0)
 			return act_id;
 
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
index 9a22cdda6bbd..2f7f5e44d28c 100644
--- a/net/sched/act_sample.c
+++ b/net/sched/act_sample.c
@@ -291,7 +291,8 @@ static void tcf_offload_sample_get_group(struct flow_action_entry *entry,
 }
 
 static int tcf_sample_offload_act_setup(struct tc_action *act, void *entry_data,
-					u32 *index_inc, bool bind)
+					u32 *index_inc, bool bind,
+					struct netlink_ext_ack *extack)
 {
 	if (bind) {
 		struct flow_action_entry *entry = entry_data;
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index ceba11b198bb..8cd8e506c9c9 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -328,7 +328,8 @@ static size_t tcf_skbedit_get_fill_size(const struct tc_action *act)
 }
 
 static int tcf_skbedit_offload_act_setup(struct tc_action *act, void *entry_data,
-					 u32 *index_inc, bool bind)
+					 u32 *index_inc, bool bind,
+					 struct netlink_ext_ack *extack)
 {
 	if (bind) {
 		struct flow_action_entry *entry = entry_data;
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
index 23aba03d26a8..3c6f40478c81 100644
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -808,7 +808,8 @@ static int tcf_tunnel_encap_get_tunnel(struct flow_action_entry *entry,
 static int tcf_tunnel_key_offload_act_setup(struct tc_action *act,
 					    void *entry_data,
 					    u32 *index_inc,
-					    bool bind)
+					    bool bind,
+					    struct netlink_ext_ack *extack)
 {
 	int err;
 
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
index 883454c4f921..8c89bce99cbd 100644
--- a/net/sched/act_vlan.c
+++ b/net/sched/act_vlan.c
@@ -369,7 +369,8 @@ static size_t tcf_vlan_get_fill_size(const struct tc_action *act)
 }
 
 static int tcf_vlan_offload_act_setup(struct tc_action *act, void *entry_data,
-				      u32 *index_inc, bool bind)
+				      u32 *index_inc, bool bind,
+				      struct netlink_ext_ack *extack)
 {
 	if (bind) {
 		struct flow_action_entry *entry = entry_data;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index f0699f39afdb..2d4dc1468a9a 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -3513,11 +3513,13 @@ EXPORT_SYMBOL(tc_cleanup_offload_action);
 
 static int tc_setup_offload_act(struct tc_action *act,
 				struct flow_action_entry *entry,
-				u32 *index_inc)
+				u32 *index_inc,
+				struct netlink_ext_ack *extack)
 {
 #ifdef CONFIG_NET_CLS_ACT
 	if (act->ops->offload_act_setup)
-		return act->ops->offload_act_setup(act, entry, index_inc, true);
+		return act->ops->offload_act_setup(act, entry, index_inc, true,
+						   extack);
 	else
 		return -EOPNOTSUPP;
 #else
@@ -3526,7 +3528,8 @@ static int tc_setup_offload_act(struct tc_action *act,
 }
 
 int tc_setup_action(struct flow_action *flow_action,
-		    struct tc_action *actions[])
+		    struct tc_action *actions[],
+		    struct netlink_ext_ack *extack)
 {
 	int i, j, index, err = 0;
 	struct tc_action *act;
@@ -3551,7 +3554,7 @@ int tc_setup_action(struct flow_action *flow_action,
 		entry->hw_stats = tc_act_hw_stats(act->hw_stats);
 		entry->hw_index = act->tcfa_index;
 		index = 0;
-		err = tc_setup_offload_act(act, entry, &index);
+		err = tc_setup_offload_act(act, entry, &index, extack);
 		if (!err)
 			j += index;
 		else
@@ -3570,13 +3573,14 @@ int tc_setup_action(struct flow_action *flow_action,
 }
 
 int tc_setup_offload_action(struct flow_action *flow_action,
-			    const struct tcf_exts *exts)
+			    const struct tcf_exts *exts,
+			    struct netlink_ext_ack *extack)
 {
 #ifdef CONFIG_NET_CLS_ACT
 	if (!exts)
 		return 0;
 
-	return tc_setup_action(flow_action, exts->actions);
+	return tc_setup_action(flow_action, exts->actions, extack);
 #else
 	return 0;
 #endif
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index ed5e6f08e74a..cddacf49f9e8 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -464,7 +464,8 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
 	cls_flower.rule->match.key = &f->mkey;
 	cls_flower.classid = f->res.classid;
 
-	err = tc_setup_offload_action(&cls_flower.rule->action, &f->exts);
+	err = tc_setup_offload_action(&cls_flower.rule->action, &f->exts,
+				      cls_flower.common.extack);
 	if (err) {
 		kfree(cls_flower.rule);
 		if (skip_sw) {
@@ -2362,7 +2363,8 @@ static int fl_reoffload(struct tcf_proto *tp, bool add, flow_setup_cb_t *cb,
 		cls_flower.rule->match.mask = &f->mask->key;
 		cls_flower.rule->match.key = &f->mkey;
 
-		err = tc_setup_offload_action(&cls_flower.rule->action, &f->exts);
+		err = tc_setup_offload_action(&cls_flower.rule->action, &f->exts,
+					      cls_flower.common.extack);
 		if (err) {
 			kfree(cls_flower.rule);
 			if (tc_skip_sw(f->flags)) {
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index ca5670fd5228..df80c6b185a0 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -97,7 +97,8 @@ static int mall_replace_hw_filter(struct tcf_proto *tp,
 	cls_mall.command = TC_CLSMATCHALL_REPLACE;
 	cls_mall.cookie = cookie;
 
-	err = tc_setup_offload_action(&cls_mall.rule->action, &head->exts);
+	err = tc_setup_offload_action(&cls_mall.rule->action, &head->exts,
+				      cls_mall.common.extack);
 	if (err) {
 		kfree(cls_mall.rule);
 		mall_destroy_hw_filter(tp, head, cookie, NULL);
@@ -302,7 +303,8 @@ static int mall_reoffload(struct tcf_proto *tp, bool add, flow_setup_cb_t *cb,
 		TC_CLSMATCHALL_REPLACE : TC_CLSMATCHALL_DESTROY;
 	cls_mall.cookie = (unsigned long)head;
 
-	err = tc_setup_offload_action(&cls_mall.rule->action, &head->exts);
+	err = tc_setup_offload_action(&cls_mall.rule->action, &head->exts,
+				      cls_mall.common.extack);
 	if (err) {
 		kfree(cls_mall.rule);
 		if (add && tc_skip_sw(head->flags)) {
diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index 87bdd71c7bb6..f70112176b7c 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c
@@ -332,6 +332,7 @@ static void __xp_dma_unmap(struct xsk_dma_map *dma_map, unsigned long attrs)
 	for (i = 0; i < dma_map->dma_pages_cnt; i++) {
 		dma = &dma_map->dma_pages[i];
 		if (*dma) {
+			*dma &= ~XSK_NEXT_PG_CONTIG_MASK;
 			dma_unmap_page_attrs(dma_map->dev, *dma, PAGE_SIZE,
 					     DMA_BIDIRECTIONAL, attrs);
 			*dma = 0;
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index bd60308769ff..8634004a606b 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -74,36 +74,36 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
 	err = snd_cs46xx_create(card, pci,
 				external_amp[dev], thinkpad[dev]);
 	if (err < 0)
-		return err;
+		goto error;
 	card->private_data = chip;
 	chip->accept_valid = mmap_valid[dev];
 	err = snd_cs46xx_pcm(chip, 0);
 	if (err < 0)
-		return err;
+		goto error;
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	err = snd_cs46xx_pcm_rear(chip, 1);
 	if (err < 0)
-		return err;
+		goto error;
 	err = snd_cs46xx_pcm_iec958(chip, 2);
 	if (err < 0)
-		return err;
+		goto error;
 #endif
 	err = snd_cs46xx_mixer(chip, 2);
 	if (err < 0)
-		return err;
+		goto error;
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	if (chip->nr_ac97_codecs ==2) {
 		err = snd_cs46xx_pcm_center_lfe(chip, 3);
 		if (err < 0)
-			return err;
+			goto error;
 	}
 #endif
 	err = snd_cs46xx_midi(chip, 0);
 	if (err < 0)
-		return err;
+		goto error;
 	err = snd_cs46xx_start_dsp(chip);
 	if (err < 0)
-		return err;
+		goto error;
 
 	snd_cs46xx_gameport(chip);
 
@@ -117,11 +117,15 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
 
 	err = snd_card_register(card);
 	if (err < 0)
-		return err;
+		goto error;
 
 	pci_set_drvdata(pci, card);
 	dev++;
 	return 0;
+
+ error:
+	snd_card_free(card);
+	return err;
 }
 
 static struct pci_driver cs46xx_driver = {
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index d3d786de8f4c..45f5db25a77e 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -9264,6 +9264,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x1558, 0x70f4, "Clevo NH77EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x70f6, "Clevo NH77DPQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x7716, "Clevo NS50PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+	SND_PCI_QUIRK(0x1558, 0x7718, "Clevo L140PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x8228, "Clevo NR40BU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x8520, "Clevo NH50D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x8521, "Clevo NH77D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c
index e61a8257bf64..360d61a36c35 100644
--- a/sound/soc/codecs/rt700.c
+++ b/sound/soc/codecs/rt700.c
@@ -315,17 +315,27 @@ static int rt700_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hs_jack, void *data)
 {
 	struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component);
+	int ret;
 
 	rt700->hs_jack = hs_jack;
 
-	if (!rt700->hw_init) {
-		dev_dbg(&rt700->slave->dev,
-			"%s hw_init not ready yet\n", __func__);
+	ret = pm_runtime_resume_and_get(component->dev);
+	if (ret < 0) {
+		if (ret != -EACCES) {
+			dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);
+			return ret;
+		}
+
+		/* pm_runtime not enabled yet */
+		dev_dbg(component->dev,	"%s: skipping jack init for now\n", __func__);
 		return 0;
 	}
 
 	rt700_jack_init(rt700);
 
+	pm_runtime_mark_last_busy(component->dev);
+	pm_runtime_put_autosuspend(component->dev);
+
 	return 0;
 }
 
diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c
index bdb1375f0338..9d59e653b941 100644
--- a/sound/soc/codecs/rt711-sdca.c
+++ b/sound/soc/codecs/rt711-sdca.c
@@ -487,16 +487,27 @@ static int rt711_sdca_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hs_jack, void *data)
 {
 	struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component);
+	int ret;
 
 	rt711->hs_jack = hs_jack;
 
-	if (!rt711->hw_init) {
-		dev_dbg(&rt711->slave->dev,
-			"%s hw_init not ready yet\n", __func__);
+	ret = pm_runtime_resume_and_get(component->dev);
+	if (ret < 0) {
+		if (ret != -EACCES) {
+			dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);
+			return ret;
+		}
+
+		/* pm_runtime not enabled yet */
+		dev_dbg(component->dev,	"%s: skipping jack init for now\n", __func__);
 		return 0;
 	}
 
 	rt711_sdca_jack_init(rt711);
+
+	pm_runtime_mark_last_busy(component->dev);
+	pm_runtime_put_autosuspend(component->dev);
+
 	return 0;
 }
 
@@ -1190,14 +1201,6 @@ static int rt711_sdca_probe(struct snd_soc_component *component)
 	return 0;
 }
 
-static void rt711_sdca_remove(struct snd_soc_component *component)
-{
-	struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component);
-
-	regcache_cache_only(rt711->regmap, true);
-	regcache_cache_only(rt711->mbq_regmap, true);
-}
-
 static const struct snd_soc_component_driver soc_sdca_dev_rt711 = {
 	.probe = rt711_sdca_probe,
 	.controls = rt711_sdca_snd_controls,
@@ -1207,7 +1210,7 @@ static const struct snd_soc_component_driver soc_sdca_dev_rt711 = {
 	.dapm_routes = rt711_sdca_audio_map,
 	.num_dapm_routes = ARRAY_SIZE(rt711_sdca_audio_map),
 	.set_jack = rt711_sdca_set_jack_detect,
-	.remove = rt711_sdca_remove,
+	.endianness = 1,
 };
 
 static int rt711_sdca_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c
index ea25fd58d43a..9958067e80f1 100644
--- a/sound/soc/codecs/rt711.c
+++ b/sound/soc/codecs/rt711.c
@@ -457,17 +457,27 @@ static int rt711_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hs_jack, void *data)
 {
 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
+	int ret;
 
 	rt711->hs_jack = hs_jack;
 
-	if (!rt711->hw_init) {
-		dev_dbg(&rt711->slave->dev,
-			"%s hw_init not ready yet\n", __func__);
+	ret = pm_runtime_resume_and_get(component->dev);
+	if (ret < 0) {
+		if (ret != -EACCES) {
+			dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);
+			return ret;
+		}
+
+		/* pm_runtime not enabled yet */
+		dev_dbg(component->dev,	"%s: skipping jack init for now\n", __func__);
 		return 0;
 	}
 
 	rt711_jack_init(rt711);
 
+	pm_runtime_mark_last_busy(component->dev);
+	pm_runtime_put_autosuspend(component->dev);
+
 	return 0;
 }
 
@@ -932,13 +942,6 @@ static int rt711_probe(struct snd_soc_component *component)
 	return 0;
 }
 
-static void rt711_remove(struct snd_soc_component *component)
-{
-	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
-
-	regcache_cache_only(rt711->regmap, true);
-}
-
 static const struct snd_soc_component_driver soc_codec_dev_rt711 = {
 	.probe = rt711_probe,
 	.set_bias_level = rt711_set_bias_level,
@@ -949,7 +952,7 @@ static const struct snd_soc_component_driver soc_codec_dev_rt711 = {
 	.dapm_routes = rt711_audio_map,
 	.num_dapm_routes = ARRAY_SIZE(rt711_audio_map),
 	.set_jack = rt711_set_jack_detect,
-	.remove = rt711_remove,
+	.endianness = 1,
 };
 
 static int rt711_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index 19c4a90ec1ea..ee59ef36b85a 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -147,6 +147,12 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
 	cfg.num_channels = runtime->channels;
 	cfg.bit_width = prtd->bits_per_sample;
 
+	if (prtd->state) {
+		/* clear the previous setup if any  */
+		q6apm_graph_stop(prtd->graph);
+		q6apm_unmap_memory_regions(prtd->graph, substream->stream);
+	}
+
 	prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
 	prtd->pos = 0;
 	/* rate and channels are sent to audio driver */
diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c
index dc1f743730c0..6888e0a4665d 100644
--- a/sound/soc/sof/intel/hda-pcm.c
+++ b/sound/soc/sof/intel/hda-pcm.c
@@ -192,79 +192,7 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
 		goto found;
 	}
 
-	switch (sof_hda_position_quirk) {
-	case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY:
-		/*
-		 * This legacy code, inherited from the Skylake driver,
-		 * mixes DPIB registers and DPIB DDR updates and
-		 * does not seem to follow any known hardware recommendations.
-		 * It's not clear e.g. why there is a different flow
-		 * for capture and playback, the only information that matters is
-		 * what traffic class is used, and on all SOF-enabled platforms
-		 * only VC0 is supported so the work-around was likely not necessary
-		 * and quite possibly wrong.
-		 */
-
-		/* DPIB/posbuf position mode:
-		 * For Playback, Use DPIB register from HDA space which
-		 * reflects the actual data transferred.
-		 * For Capture, Use the position buffer for pointer, as DPIB
-		 * is not accurate enough, its update may be completed
-		 * earlier than the data written to DDR.
-		 */
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-			pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
-					       AZX_REG_VS_SDXDPIB_XBASE +
-					       (AZX_REG_VS_SDXDPIB_XINTERVAL *
-						hstream->index));
-		} else {
-			/*
-			 * For capture stream, we need more workaround to fix the
-			 * position incorrect issue:
-			 *
-			 * 1. Wait at least 20us before reading position buffer after
-			 * the interrupt generated(IOC), to make sure position update
-			 * happens on frame boundary i.e. 20.833uSec for 48KHz.
-			 * 2. Perform a dummy Read to DPIB register to flush DMA
-			 * position value.
-			 * 3. Read the DMA Position from posbuf. Now the readback
-			 * value should be >= period boundary.
-			 */
-			usleep_range(20, 21);
-			snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
-					 AZX_REG_VS_SDXDPIB_XBASE +
-					 (AZX_REG_VS_SDXDPIB_XINTERVAL *
-					  hstream->index));
-			pos = snd_hdac_stream_get_pos_posbuf(hstream);
-		}
-		break;
-	case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS:
-		/*
-		 * In case VC1 traffic is disabled this is the recommended option
-		 */
-		pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
-				       AZX_REG_VS_SDXDPIB_XBASE +
-				       (AZX_REG_VS_SDXDPIB_XINTERVAL *
-					hstream->index));
-		break;
-	case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE:
-		/*
-		 * This is the recommended option when VC1 is enabled.
-		 * While this isn't needed for SOF platforms it's added for
-		 * consistency and debug.
-		 */
-		pos = snd_hdac_stream_get_pos_posbuf(hstream);
-		break;
-	default:
-		dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n",
-			     sof_hda_position_quirk);
-		pos = 0;
-		break;
-	}
-
-	if (pos >= hstream->bufsize)
-		pos = 0;
-
+	pos = hda_dsp_stream_get_position(hstream, substream->stream, true);
 found:
 	pos = bytes_to_frames(substream->runtime, pos);
 
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index daeb64c495e4..d95ae17e81cc 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -707,12 +707,13 @@ bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev)
 }
 
 static void
-hda_dsp_set_bytes_transferred(struct hdac_stream *hstream, u64 buffer_size)
+hda_dsp_compr_bytes_transferred(struct hdac_stream *hstream, int direction)
 {
+	u64 buffer_size = hstream->bufsize;
 	u64 prev_pos, pos, num_bytes;
 
 	div64_u64_rem(hstream->curr_pos, buffer_size, &prev_pos);
-	pos = snd_hdac_stream_get_pos_posbuf(hstream);
+	pos = hda_dsp_stream_get_position(hstream, direction, false);
 
 	if (pos < prev_pos)
 		num_bytes = (buffer_size - prev_pos) +  pos;
@@ -748,8 +749,7 @@ static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status)
 			if (s->substream && sof_hda->no_ipc_position) {
 				snd_sof_pcm_period_elapsed(s->substream);
 			} else if (s->cstream) {
-				hda_dsp_set_bytes_transferred(s,
-					s->cstream->runtime->buffer_size);
+				hda_dsp_compr_bytes_transferred(s, s->cstream->direction);
 				snd_compr_fragment_elapsed(s->cstream);
 			}
 		}
@@ -1009,3 +1009,89 @@ void hda_dsp_stream_free(struct snd_sof_dev *sdev)
 		devm_kfree(sdev->dev, hda_stream);
 	}
 }
+
+snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream,
+					      int direction, bool can_sleep)
+{
+	struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
+	struct sof_intel_hda_stream *hda_stream = hstream_to_sof_hda_stream(hext_stream);
+	struct snd_sof_dev *sdev = hda_stream->sdev;
+	snd_pcm_uframes_t pos;
+
+	switch (sof_hda_position_quirk) {
+	case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY:
+		/*
+		 * This legacy code, inherited from the Skylake driver,
+		 * mixes DPIB registers and DPIB DDR updates and
+		 * does not seem to follow any known hardware recommendations.
+		 * It's not clear e.g. why there is a different flow
+		 * for capture and playback, the only information that matters is
+		 * what traffic class is used, and on all SOF-enabled platforms
+		 * only VC0 is supported so the work-around was likely not necessary
+		 * and quite possibly wrong.
+		 */
+
+		/* DPIB/posbuf position mode:
+		 * For Playback, Use DPIB register from HDA space which
+		 * reflects the actual data transferred.
+		 * For Capture, Use the position buffer for pointer, as DPIB
+		 * is not accurate enough, its update may be completed
+		 * earlier than the data written to DDR.
+		 */
+		if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+			pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
+					       AZX_REG_VS_SDXDPIB_XBASE +
+					       (AZX_REG_VS_SDXDPIB_XINTERVAL *
+						hstream->index));
+		} else {
+			/*
+			 * For capture stream, we need more workaround to fix the
+			 * position incorrect issue:
+			 *
+			 * 1. Wait at least 20us before reading position buffer after
+			 * the interrupt generated(IOC), to make sure position update
+			 * happens on frame boundary i.e. 20.833uSec for 48KHz.
+			 * 2. Perform a dummy Read to DPIB register to flush DMA
+			 * position value.
+			 * 3. Read the DMA Position from posbuf. Now the readback
+			 * value should be >= period boundary.
+			 */
+			if (can_sleep)
+				usleep_range(20, 21);
+
+			snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
+					 AZX_REG_VS_SDXDPIB_XBASE +
+					 (AZX_REG_VS_SDXDPIB_XINTERVAL *
+					  hstream->index));
+			pos = snd_hdac_stream_get_pos_posbuf(hstream);
+		}
+		break;
+	case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS:
+		/*
+		 * In case VC1 traffic is disabled this is the recommended option
+		 */
+		pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
+				       AZX_REG_VS_SDXDPIB_XBASE +
+				       (AZX_REG_VS_SDXDPIB_XINTERVAL *
+					hstream->index));
+		break;
+	case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE:
+		/*
+		 * This is the recommended option when VC1 is enabled.
+		 * While this isn't needed for SOF platforms it's added for
+		 * consistency and debug.
+		 */
+		pos = snd_hdac_stream_get_pos_posbuf(hstream);
+		break;
+	default:
+		dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n",
+			     sof_hda_position_quirk);
+		pos = 0;
+		break;
+	}
+
+	if (pos >= hstream->bufsize)
+		pos = 0;
+
+	return pos;
+}
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 05e5e158614a..196494ba1245 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -557,6 +557,9 @@ int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
 bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev);
 bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev);
 
+snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream,
+					      int direction, bool can_sleep);
+
 struct hdac_ext_stream *
 	hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags);
 int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag);
diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c
index cdff48c4195f..80fb82ece38d 100644
--- a/sound/soc/sof/ipc3-topology.c
+++ b/sound/soc/sof/ipc3-topology.c
@@ -1578,24 +1578,23 @@ static int sof_ipc3_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_
 	struct sof_ipc_ctrl_data *cdata;
 	int ret;
 
-	scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL);
-	if (!scontrol->ipc_control_data)
-		return -ENOMEM;
-
-	if (scontrol->max_size < sizeof(*cdata) ||
-	    scontrol->max_size < sizeof(struct sof_abi_hdr)) {
-		ret = -EINVAL;
-		goto err;
+	if (scontrol->max_size < (sizeof(*cdata) + sizeof(struct sof_abi_hdr))) {
+		dev_err(sdev->dev, "%s: insufficient size for a bytes control: %zu.\n",
+			__func__, scontrol->max_size);
+		return -EINVAL;
 	}
 
-	/* init the get/put bytes data */
 	if (scontrol->priv_size > scontrol->max_size - sizeof(*cdata)) {
-		dev_err(sdev->dev, "err: bytes data size %zu exceeds max %zu.\n",
+		dev_err(sdev->dev,
+			"%s: bytes data size %zu exceeds max %zu.\n", __func__,
 			scontrol->priv_size, scontrol->max_size - sizeof(*cdata));
-		ret = -EINVAL;
-		goto err;
+		return -EINVAL;
 	}
 
+	scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL);
+	if (!scontrol->ipc_control_data)
+		return -ENOMEM;
+
 	scontrol->size = sizeof(struct sof_ipc_ctrl_data) + scontrol->priv_size;
 
 	cdata = scontrol->ipc_control_data;
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index e8468f9b007d..12ce69b04f63 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1842,6 +1842,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
 	DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */
 		   QUIRK_FLAG_GET_SAMPLE_RATE),
+	DEVICE_FLG(0x1397, 0x0508, /* Behringer UMC204HD */
+		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
+	DEVICE_FLG(0x1397, 0x0509, /* Behringer UMC404HD */
+		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
 	DEVICE_FLG(0x13e5, 0x0001, /* Serato Phono */
 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
 	DEVICE_FLG(0x154e, 0x1002, /* Denon DCD-1500RE */
diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
index 664b9ecaf228..063da0d53462 100644
--- a/tools/testing/selftests/net/forwarding/lib.sh
+++ b/tools/testing/selftests/net/forwarding/lib.sh
@@ -1176,6 +1176,7 @@ learning_test()
 	# FDB entry was installed.
 	bridge link set dev $br_port1 flood off
 
+	ip link set $host1_if promisc on
 	tc qdisc add dev $host1_if ingress
 	tc filter add dev $host1_if ingress protocol ip pref 1 handle 101 \
 		flower dst_mac $mac action drop
@@ -1186,7 +1187,7 @@ learning_test()
 	tc -j -s filter show dev $host1_if ingress \
 		| jq -e ".[] | select(.options.handle == 101) \
 		| select(.options.actions[0].stats.packets == 1)" &> /dev/null
-	check_fail $? "Packet reached second host when should not"
+	check_fail $? "Packet reached first host when should not"
 
 	$MZ $host1_if -c 1 -p 64 -a $mac -t ip -q
 	sleep 1
@@ -1225,6 +1226,7 @@ learning_test()
 
 	tc filter del dev $host1_if ingress protocol ip pref 1 handle 101 flower
 	tc qdisc del dev $host1_if ingress
+	ip link set $host1_if promisc off
 
 	bridge link set dev $br_port1 flood on
 
@@ -1242,6 +1244,7 @@ flood_test_do()
 
 	# Add an ACL on `host2_if` which will tell us whether the packet
 	# was flooded to it or not.
+	ip link set $host2_if promisc on
 	tc qdisc add dev $host2_if ingress
 	tc filter add dev $host2_if ingress protocol ip pref 1 handle 101 \
 		flower dst_mac $mac action drop
@@ -1259,6 +1262,7 @@ flood_test_do()
 
 	tc filter del dev $host2_if ingress protocol ip pref 1 handle 101 flower
 	tc qdisc del dev $host2_if ingress
+	ip link set $host2_if promisc off
 
 	return $err
 }
diff --git a/tools/testing/selftests/net/udpgro.sh b/tools/testing/selftests/net/udpgro.sh
index f8a19f548ae9..ebbd0b282432 100755
--- a/tools/testing/selftests/net/udpgro.sh
+++ b/tools/testing/selftests/net/udpgro.sh
@@ -34,7 +34,7 @@ cfg_veth() {
 	ip -netns "${PEER_NS}" addr add dev veth1 192.168.1.1/24
 	ip -netns "${PEER_NS}" addr add dev veth1 2001:db8::1/64 nodad
 	ip -netns "${PEER_NS}" link set dev veth1 up
-	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy
+	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp
 }
 
 run_one() {
diff --git a/tools/testing/selftests/net/udpgro_bench.sh b/tools/testing/selftests/net/udpgro_bench.sh
index 820bc50f6b68..fad2d1a71cac 100755
--- a/tools/testing/selftests/net/udpgro_bench.sh
+++ b/tools/testing/selftests/net/udpgro_bench.sh
@@ -34,7 +34,7 @@ run_one() {
 	ip -netns "${PEER_NS}" addr add dev veth1 2001:db8::1/64 nodad
 	ip -netns "${PEER_NS}" link set dev veth1 up
 
-	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy
+	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp
 	ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} -r &
 	ip netns exec "${PEER_NS}" ./udpgso_bench_rx -t ${rx_args} -r &
 
diff --git a/tools/testing/selftests/net/udpgro_frglist.sh b/tools/testing/selftests/net/udpgro_frglist.sh
index 807b74c8fd80..832c738cc3c2 100755
--- a/tools/testing/selftests/net/udpgro_frglist.sh
+++ b/tools/testing/selftests/net/udpgro_frglist.sh
@@ -36,7 +36,7 @@ run_one() {
 	ip netns exec "${PEER_NS}" ethtool -K veth1 rx-gro-list on
 
 
-	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy
+	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp
 	tc -n "${PEER_NS}" qdisc add dev veth1 clsact
 	tc -n "${PEER_NS}" filter add dev veth1 ingress prio 4 protocol ipv6 bpf object-file ../bpf/nat6to4.o section schedcls/ingress6/nat_6  direct-action
 	tc -n "${PEER_NS}" filter add dev veth1 egress prio 4 protocol ip bpf object-file ../bpf/nat6to4.o section schedcls/egress4/snat4 direct-action
diff --git a/tools/testing/selftests/net/udpgro_fwd.sh b/tools/testing/selftests/net/udpgro_fwd.sh
index 6f05e06f6761..1bcd82e1f662 100755
--- a/tools/testing/selftests/net/udpgro_fwd.sh
+++ b/tools/testing/selftests/net/udpgro_fwd.sh
@@ -46,7 +46,7 @@ create_ns() {
 		ip -n $BASE$ns addr add dev veth$ns $BM_NET_V4$ns/24
 		ip -n $BASE$ns addr add dev veth$ns $BM_NET_V6$ns/64 nodad
 	done
-	ip -n $NS_DST link set veth$DST xdp object ../bpf/xdp_dummy.o section xdp_dummy 2>/dev/null
+	ip -n $NS_DST link set veth$DST xdp object ../bpf/xdp_dummy.o section xdp 2>/dev/null
 }
 
 create_vxlan_endpoint() {
diff --git a/tools/testing/selftests/net/veth.sh b/tools/testing/selftests/net/veth.sh
index 19eac3e44c06..430895d1a2b6 100755
--- a/tools/testing/selftests/net/veth.sh
+++ b/tools/testing/selftests/net/veth.sh
@@ -289,14 +289,14 @@ if [ $CPUS -gt 1 ]; then
 	ip netns exec $NS_SRC ethtool -L veth$SRC rx 1 tx 2 2>/dev/null
 	printf "%-60s" "bad setting: XDP with RX nr less than TX"
 	ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o \
-		section xdp_dummy 2>/dev/null &&\
+		section xdp 2>/dev/null &&\
 		echo "fail - set operation successful ?!?" || echo " ok "
 
 	# the following tests will run with multiple channels active
 	ip netns exec $NS_SRC ethtool -L veth$SRC rx 2
 	ip netns exec $NS_DST ethtool -L veth$DST rx 2
 	ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o \
-		section xdp_dummy 2>/dev/null
+		section xdp 2>/dev/null
 	printf "%-60s" "bad setting: reducing RX nr below peer TX with XDP set"
 	ip netns exec $NS_DST ethtool -L veth$DST rx 1 2>/dev/null &&\
 		echo "fail - set operation successful ?!?" || echo " ok "
@@ -311,7 +311,7 @@ if [ $CPUS -gt 2 ]; then
 	chk_channels "setting invalid channels nr" $DST 2 2
 fi
 
-ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o section xdp_dummy 2>/dev/null
+ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o section xdp 2>/dev/null
 chk_gro_flag "with xdp attached - gro flag" $DST on
 chk_gro_flag "        - peer gro flag" $SRC off
 chk_tso_flag "        - tso flag" $SRC off

^ permalink raw reply related	[relevance 5%]

* [folded-merged] mm-damon-dbgfs-implement-deprecation-notice-file-fix.patch removed from -mm tree
@ 2024-02-21 23:42  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2024-02-21 23:42 UTC (permalink / raw)
  To: mm-commits, sj, siyanteng, shuah, corbet, alexs, 2023002089, arnd,
	akpm


The quilt patch titled
     Subject: mm/damon/dbgfs: fix bogus string length
has been removed from the -mm tree.  Its filename was
     mm-damon-dbgfs-implement-deprecation-notice-file-fix.patch

This patch was dropped because it was folded into mm-damon-dbgfs-implement-deprecation-notice-file.patch

------------------------------------------------------
From: Arnd Bergmann <arnd@arndb.de>
Subject: mm/damon/dbgfs: fix bogus string length
Date: Fri, 2 Feb 2024 13:43:26 +0100

gcc correctly points out that using strnlen() on a fixed size array
is nonsense with an overlong limit:

mm/damon/dbgfs.c: In function 'damon_dbgfs_deprecated_read':
mm/damon/dbgfs.c:814:19: error: 'strnlen' specified bound 1024 exceeds source size 512 [-Werror=stringop-overread]
  814 |         int len = strnlen(kbuf, 1024);
      |                   ^~~~~~~~~~~~~~~~~~~
mm/damon/dbgfs.c:813:14: note: source object allocated here
  813 |         char kbuf[512] = DAMON_DBGFS_DEPRECATION_NOTICE;
      |              ^~~~

In fact, neither of the arbitrary limits are needed here: The first
one can just be a static const string and avoid wasting any more
space then necessary, and the strnlen() can be either strlen() or
sizeof(kbuf)-1, both of which the compiler turns into the same
constant here.

Link: https://lkml.kernel.org/r/20240202124339.892862-1-arnd@kernel.org
Fixes: adf9047adfff ("mm/damon/dbgfs: implement deprecation notice file")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: SeongJae Park <sj@kernel.org>
Cc: Alex Shi <alexs@kernel.org>
Cc: Hu Haowen <2023002089@link.tyut.edu.cn>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Yanteng Si <siyanteng@loongson.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 mm/damon/dbgfs.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

--- a/mm/damon/dbgfs.c~mm-damon-dbgfs-implement-deprecation-notice-file-fix
+++ a/mm/damon/dbgfs.c
@@ -808,13 +808,12 @@ static void dbgfs_destroy_ctx(struct dam
 static ssize_t damon_dbgfs_deprecated_read(struct file *file,
 		char __user *buf, size_t count, loff_t *ppos)
 {
-	char kbuf[512] = "DAMON debugfs interface is deprecated, "
+	static const char kbuf[512] = "DAMON debugfs interface is deprecated, "
 		     "so users should move to DAMON_SYSFS. If you cannot, "
 		     "please report your usecase to damon@lists.linux.dev and "
 		     "linux-mm@kvack.org.\n";
-	int len = strnlen(kbuf, 1024);
 
-	return simple_read_from_buffer(buf, count, ppos, kbuf, len);
+	return simple_read_from_buffer(buf, count, ppos, kbuf, strlen(kbuf));
 }
 
 /*
_

Patches currently in -mm which might be from arnd@arndb.de are

mm-damon-dbgfs-implement-deprecation-notice-file.patch
kasan-test-avoid-gcc-warning-for-intentional-overflow.patch
mm-mmu_gather-add-tlb_remove_tlb_entries-fix.patch


^ permalink raw reply	[relevance 5%]

* [PATCH v16 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-06-29  7:55  5% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-06-29  7:55 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui, tangyouling, hejinyang,
	Huacai Chen

Add maintainers for LoongArch KVM.

Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ad32db6c81cc..b6733248ec09 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11377,6 +11377,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 M:	Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
-- 
2.39.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v15 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-06-26  8:47  5% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-06-26  8:47 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui, tangyouling, Huacai Chen

Add maintainers for LoongArch KVM.

Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ad32db6c81cc..b6733248ec09 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11377,6 +11377,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 M:	Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
-- 
2.39.1


^ permalink raw reply related	[relevance 5%]

* [merged mm-stable] mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice.patch removed from -mm tree
@ 2023-02-13 23:55  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2023-02-13 23:55 UTC (permalink / raw)
  To: mm-commits, corbet, sj, akpm


The quilt patch titled
     Subject: mm/damon/Kconfig: add DAMON debugfs interface deprecation notice
has been removed from the -mm tree.  Its filename was
     mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice.patch

This patch was dropped because it was merged into the mm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: mm/damon/Kconfig: add DAMON debugfs interface deprecation notice
Date: Thu, 9 Feb 2023 19:20:08 +0000

DAMON debugfs interface has announced to be deprecated after >v5.15 LTS
kernel is released.  And, v6.1.y has announced to be an LTS[1].

Though the announcement was there for a while, some people might not
noticed that so far.  Also, some users could depend on it and have
problems at  movng to the alternative (DAMON sysfs interface).

For such cases, note DAMON debugfs interface as deprecated, and contacts
to ask helps on the Kconfig.

[1] https://git.kernel.org/pub/scm/docs/kernel/website.git/commit/?id=332e9121320bc7461b2d3a79665caf153e51732c

Link: https://lkml.kernel.org/r/20230209192009.7885-3-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---


--- a/mm/damon/Kconfig~mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice
+++ a/mm/damon/Kconfig
@@ -60,7 +60,7 @@ config DAMON_SYSFS
 	  the interface for arbitrary data access monitoring.
 
 config DAMON_DBGFS
-	bool "DAMON debugfs interface"
+	bool "DAMON debugfs interface (DEPRECATED!)"
 	depends on DAMON_VADDR && DAMON_PADDR && DEBUG_FS
 	help
 	  This builds the debugfs interface for DAMON.  The user space admins
@@ -68,8 +68,9 @@ config DAMON_DBGFS
 
 	  If unsure, say N.
 
-	  This will be removed after >5.15.y LTS kernel is released, so users
-	  should move to the sysfs interface (DAMON_SYSFS).
+	  This is deprecated, so users should move to the sysfs interface
+	  (DAMON_SYSFS).  If you depend on this and cannot move, please report
+	  your usecase to damon@lists.linux.dev and linux-mm@kvack.org.
 
 config DAMON_DBGFS_KUNIT_TEST
 	bool "Test for damon debugfs interface" if !KUNIT_ALL_TESTS
_

Patches currently in -mm which might be from sj@kernel.org are



^ permalink raw reply	[relevance 5%]

* Re: Is the data rate estimation for 5GHz channels overly pessimistic?
  @ 2023-10-21 23:23  5%                   ` Simonas Kazlauskas
  0 siblings, 0 replies; 200+ results
From: Simonas Kazlauskas @ 2023-10-21 23:23 UTC (permalink / raw)
  To: James Prestwood; +Cc: iwd, Denis Kenzior

[-- Attachment #1: Type: text/plain, Size: 3107 bytes --]

Hey,

I finally got around to figuring out the test specifications (I think.) At least 
the test results I’m seeing are the same as the output from `iwd -d`.

See the attached patch (feel free to merge it, or not to merge it – entirely up 
to you.)

72Mbps appears to be coming from the table for 80MHz rates (NSS=2 so 36MHz in 
the table itself), but this *should* be a 40MHz ordeal. My APs are set up for 
40MHz 5GHz channels and 160MHz 6GHz channels, but it seems like it might still 
be sending capabilities that include 80MHz support…? Weird.

[1]: https://semfionetworks.com/blog/mcs-table-updated-with-80211ax-data-rates/

Anyhow, besides the 80MHz weirdness, this all seems to ultimately come down to 
the `ht_vht_he_base_rssi` table (as you both have pointed out in the very 
beginning!) After the `width_adjust` in `band_he_rate` is applied, -76dBm is the 
bare minimum for it to pick out even the lowest 36MHz rate from the 80MHz table. 

Meanwhile in practice I’m getting MCS anywhere from 4 to 10 (seems to be fairly 
random regardless of the signal strength, which varies between -72dBm and -79dBm 
this particular evening.) The only caveat is that for very high MCS values (8, 
9, 10), NSS appears to drop down to 1 (thus making them roughly equivalent to 
MCS 4-to-5).

I’m not sure if this stellar MCS behaviour is Ubiquiti’s doing something fancy, 
or if its a result of those aforementioned thick walls, which *also* happen to 
block out any interference from the neighbours as well (making my APs literally 
the only transmitter in the 5GHz band devices bother noticing…) 

I have no clue if there’s anything actionable here, but I’m happy to help with 
testing the observed behaviour at various signal strengths if coming up with a 
better `ht_vht_he_base_rssi` table is… on the table :)

Have a great weekend,
S.

Simonas Kazlauskas wrote:
>James,
>
>Thank you for implementing the display of HE capabilities in `iwmon` – 
>these do indeed show up in my scans now, false alert there.
>
>>HE Capabilities: len 34
>>    HE supported channel width set: bit  1: 40MHz/80MHz supported (5GHz/6GHz)
>>        Rx HE-MCS Map <= 80MHz 1 Streams: MCS 0-11 supported
>>        Rx HE-MCS Map <= 80MHz 2 Streams: MCS 0-11 supported
>>        Rx HE-MCS Map <= 80MHz 3 Streams: MCS 0-11 supported
>>        Rx HE-MCS Map <= 80MHz 4 Streams: MCS 0-11 supported
>>        Tx HE-MCS Map <= 80MHz 1 Streams: MCS 0-11 supported
>>        Tx HE-MCS Map <= 80MHz 2 Streams: MCS 0-11 supported
>>        Tx HE-MCS Map <= 80MHz 3 Streams: MCS 0-11 supported
>>        Tx HE-MCS Map <= 80MHz 4 Streams: MCS 0-11 supported
>>    0d 01 08 9a 40 10 04 60 48 88 1f 43 81 1c 11 08  ....@..`H..C....
>>    00 aa ff aa ff 7b 1c c7 71 1c c7 71 1c c7 71 1c  .....{..q..q..q.
>>    c7 71                                            .q
>
>I’ve sent you and Denis both the pcap of the scan. I, unforunately, 
>don’t think I’ll be able to hack on the test and/or data rate 
>investigation much further before the weekend, but I’m happy to test 
>out patches and such at any time.
>
>Thanks,
>S.

[-- Attachment #2: 0001-test-band-HE-band-test-with-real-world-capabilities.patch --]
[-- Type: text/plain, Size: 2590 bytes --]

From 6961629e93d9e74f5760c5be00393459ad55c0b5 Mon Sep 17 00:00:00 2001
From: Simonas Kazlauskas <git@kazlauskas.me>
Date: Sun, 22 Oct 2023 00:46:38 +0300
Subject: [PATCH] test-band: HE band test with real-world capabilities
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

I've been observing that the rate estimations in the real world usage
end up being quite a bit different from the rates that end up being used
after the association. In this commit I’m adding a test case with the
capabilities from two physical devices, if only to demonstrate the
how the rate estimation behaves in such circumstances.
---
 unit/test-band.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/unit/test-band.c b/unit/test-band.c
index e27531f7..fec09e61 100644
--- a/unit/test-band.c
+++ b/unit/test-band.c
@@ -294,7 +294,7 @@ struct he_test_data {
 	/* Own capabilities */
 	struct band_he_capabilities capabilities;
 	/* Peer HE Capabilities IE */
-	uint8_t he_capabilities[31];
+	uint8_t he_capabilities[36];
 
 };
 
@@ -366,6 +366,31 @@ const struct he_test_data he_test_5_20mhz_mcs_7_nss_1 = {
 	},
 };
 
+/* 5GHz, 40MHz With data from a real-world Unifi’s U6 Enterprise AP and a client
+ * with the Intel AX201 card.
+ */
+const struct he_test_data he_test_5_40mhz_unifi_ap_and_ax201 = {
+	.freq = BAND_FREQ_5_GHZ,
+	.rssi = -76,
+	// In practice seems to be more like 275_200_000ULL instead...
+	.expected_rate = 72000000ULL,
+	.capabilities = {
+		.he_mcs_set = {
+			HE_MCS_SET(MCS11, 2), HE_MCS_SET(MCS11, 1), MCS_UNSUP
+		},
+		.he_phy_capa = {
+			0x0e, 0x3f, 0x0e, 0x09, 0xfd, 0x09, 0x8c, 0x16, 0x0f, 0xf0, 0x01
+		},
+		.iftypes = 1 << NETDEV_IFTYPE_STATION,
+	},
+	.he_capabilities = {
+		0x22, IE_TYPE_HE_CAPABILITIES - 256,
+		0x0d, 0x01, 0x08, 0x9a, 0x40, 0x10, 0x04, 0x60, 0x48, 0x88, 0x1f, 0x43,
+		0x81, 0x1c, 0x11, 0x08, 0x00, 0xaa, 0xff, 0xaa, 0xff, 0x7b, 0x1c, 0xc7,
+		0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71,
+	},
+};
+
 /* 5GHz, 80MHz, MCS 7, NSS 1 */
 const struct he_test_data he_test_5_80mhz_mcs_7_nss_1 = {
 	.freq = BAND_FREQ_5_GHZ,
@@ -698,6 +723,8 @@ int main(int argc, char *argv[])
 					&he_all_mcs_unsupported);
 	l_test_add("/band/HE/test/low RSSI", band_test_he,
 					&he_test_5_low_rssi);
+	l_test_add("/band/HE/test/5GHz/40MHz/Unifi+AX201", band_test_he,
+					&he_test_5_40mhz_unifi_ap_and_ax201);
 
 	l_test_add("/band/oci2freq 1", test_oci2freq, &oci2freq_data_1);
 	l_test_add("/band/oci2freq 2", test_oci2freq, &oci2freq_data_2);
-- 
2.41.0


^ permalink raw reply related	[relevance 5%]

* [PATCH v17 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-07-20  6:28  5% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-07-20  6:28 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui, Huacai Chen

Add maintainers for LoongArch KVM.

Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index aee340630eca..4cd9067dad12 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11425,6 +11425,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 L:	linux-mips@vger.kernel.org
-- 
2.39.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v18 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-08-03  2:21  5% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-08-03  2:21 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui, Huacai Chen

Add maintainers for LoongArch KVM.

Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index aee340630eca..4cd9067dad12 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11425,6 +11425,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 L:	linux-mips@vger.kernel.org
-- 
2.39.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v19 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-08-17 12:59  5% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-08-17 12:59 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui, Huacai Chen

Add maintainers for LoongArch KVM.

Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 53b7ca804465..b1043a06f3ec 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11428,6 +11428,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 L:	linux-mips@vger.kernel.org
-- 
2.39.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v2 1/1] MAINTAINERS: Add entries for NXP(Freescale) eDMA drivers
  @ 2023-08-24 16:39  5%   ` Frank Li
  0 siblings, 0 replies; 200+ results
From: Frank Li @ 2023-08-24 16:39 UTC (permalink / raw)
  To: festevam
  Cc: Frank.Li, clin, conor+dt, devicetree, eagle.zhou, imx, joy.zou,
	kernel, krzysztof.kozlowski+dt, leoyang.li, linux-arm-kernel,
	linux-imx, linux-kernel, pierre.gondois, robh+dt, s.hauer,
	shawnguo, shenwei.wang, sherry.sun

Add the MAINTAINERS entries for NXP(Freescale) eDMA drivers

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---

Notes:
    Change from v1 to v2
    - alphabetical order

 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 23eafda02056..fbab3c404eb9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8215,6 +8215,14 @@ S:	Maintained
 F:	drivers/mmc/host/sdhci-esdhc-mcf.c
 F:	include/linux/platform_data/mmc-esdhc-mcf.h
 
+FREESCALE eDMA DRIVER
+M:	Frank Li <Frank.Li@nxp.com>
+L:	imx@lists.linux.dev
+L:	dmaengine@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/dma/fsl,edma.yaml
+F:	drivers/dma/fsl-edma*.*
+
 FREESCALE DIU FRAMEBUFFER DRIVER
 M:	Timur Tabi <timur@kernel.org>
 L:	linux-fbdev@vger.kernel.org
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH v20 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-08-31  8:30  5% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-08-31  8:30 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui, Huacai Chen

Add maintainers for LoongArch KVM.

Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 242178802c..11eb27dd66 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11472,6 +11472,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 L:	linux-mips@vger.kernel.org
-- 
2.27.0


^ permalink raw reply related	[relevance 5%]

* [PATCH v21 29/29] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-09-15  1:49  5% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-09-15  1:49 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui, Huacai Chen

Add maintainers for LoongArch KVM.

Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 79630b7d94..2f99e033d8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11523,6 +11523,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 L:	linux-mips@vger.kernel.org
-- 
2.39.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v22 25/25] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-09-27  3:09  5% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-09-27  3:09 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui, Huacai Chen

Add maintainers for LoongArch KVM.

Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index bf0f54c24f..2ff07a4ba5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11523,6 +11523,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 L:	linux-mips@vger.kernel.org
-- 
2.39.3


^ permalink raw reply related	[relevance 5%]

* [PATCH v14 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-06-19  8:32  5% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-06-19  8:32 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui, tangyouling

Add maintainers for LoongArch KVM.

Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 27ef11624748..44db717f90c2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11357,6 +11357,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 M:	Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
-- 
2.39.1


^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: update Tzung-Bi's email address
@ 2022-10-25  2:04  5% Tzung-Bi Shih
  0 siblings, 0 replies; 200+ results
From: Tzung-Bi Shih @ 2022-10-25  2:04 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, tzungbi

Use kernel.org account instead.

Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
---
 .../devicetree/bindings/sound/google,cros-ec-codec.yaml         | 2 +-
 Documentation/devicetree/bindings/sound/realtek,rt1015p.yaml    | 2 +-
 MAINTAINERS                                                     | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
index c3e9f3485449..dea293f403d9 100644
--- a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
+++ b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
@@ -8,7 +8,7 @@ title: Audio codec controlled by ChromeOS EC
 
 maintainers:
   - Cheng-Yi Chiang <cychiang@chromium.org>
-  - Tzung-Bi Shih <tzungbi@google.com>
+  - Tzung-Bi Shih <tzungbi@kernel.org>
 
 description: |
   Google's ChromeOS EC codec is a digital mic codec provided by the
diff --git a/Documentation/devicetree/bindings/sound/realtek,rt1015p.yaml b/Documentation/devicetree/bindings/sound/realtek,rt1015p.yaml
index 1d73204451b1..ea7d4900ee4a 100644
--- a/Documentation/devicetree/bindings/sound/realtek,rt1015p.yaml
+++ b/Documentation/devicetree/bindings/sound/realtek,rt1015p.yaml
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Realtek rt1015p codec devicetree bindings
 
 maintainers:
-  - Tzung-Bi Shih <tzungbi@google.com>
+  - Tzung-Bi Shih <tzungbi@kernel.org>
 
 description: |
   Rt1015p is a rt1015 variant which does not support I2C and
diff --git a/MAINTAINERS b/MAINTAINERS
index cf0f18502372..f9749afc0b9d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4906,7 +4906,7 @@ F:	drivers/platform/chrome/
 
 CHROMEOS EC CODEC DRIVER
 M:	Cheng-Yi Chiang <cychiang@chromium.org>
-M:	Tzung-Bi Shih <tzungbi@google.com>
+M:	Tzung-Bi Shih <tzungbi@kernel.org>
 R:	Guenter Roeck <groeck@chromium.org>
 L:	chrome-platform@lists.linux.dev
 S:	Maintained
-- 
2.38.0.135.g90850a2211-goog


^ permalink raw reply related	[relevance 5%]

* + docs-mm-damon-add-a-maintainer-profile-for-damon.patch added to mm-unstable branch
@ 2023-01-10 22:41  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2023-01-10 22:41 UTC (permalink / raw)
  To: mm-commits, shuah, corbet, sj, akpm


The patch titled
     Subject: Docs/mm/damon: add a maintainer-profile for DAMON
has been added to the -mm mm-unstable branch.  Its filename is
     docs-mm-damon-add-a-maintainer-profile-for-damon.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/docs-mm-damon-add-a-maintainer-profile-for-damon.patch

This patch will later appear in the mm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: Docs/mm/damon: add a maintainer-profile for DAMON
Date: Tue, 10 Jan 2023 19:03:57 +0000

Document the basic policies and expectations for DAMON development.

Link: https://lkml.kernel.org/r/20230110190400.119388-6-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 Documentation/mm/damon/index.rst              |    1 
 Documentation/mm/damon/maintainer-profile.rst |   62 ++++++++++++++++
 2 files changed, 63 insertions(+)

--- a/Documentation/mm/damon/index.rst~docs-mm-damon-add-a-maintainer-profile-for-damon
+++ a/Documentation/mm/damon/index.rst
@@ -32,3 +32,4 @@ operations with no code but simple confi
    faq
    design
    api
+   maintainer-profile
--- /dev/null
+++ a/Documentation/mm/damon/maintainer-profile.rst
@@ -0,0 +1,62 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+DAMON Maintainer Entry Profile
+==============================
+
+The DAMON subsystem covers the files that listed in 'DATA ACCESS MONITOR'
+section of 'MAINTAINERS' file.
+
+The mailing lists for the subsystem are damon@lists.linux.dev and
+linux-mm@kvack.org.  Patches should be made against the mm-unstable tree [1]_
+whenever possible and posted to the mailing lists.
+
+SCM Trees
+---------
+
+There are multiple Linux trees for DAMON development.  Patches under
+development or testing are queued in damon/next [2]_ by the DAMON maintainer.
+Suffieicntly reviewed patches will be queued in mm-unstable [1]_ by the memory
+management subsystem maintainer.  After more sufficient tests, the patches will
+be queued in mm-stable [3]_ , and finally pull-requested to the mainline by the
+memory management subsystem maintainer.
+
+Note again the patches for review should be made against the mm-unstable
+tree[1] whenever possible.  damon/next is only for preview of others' works in
+progress.
+
+Submit checklist addendum
+-------------------------
+
+When making DAMON changes, you should do below.
+
+- Build changes related outputs including kernel and documents.
+- Ensure the builds introduce no new errors or warnings.
+- Run and ensure no new failures for DAMON selftests [4]_ and kunittests [5]_ .
+
+Further doing below and putting the results will be helpful.
+
+- Run damon-tests/corr [6]_ for normal changes.
+- Run damon-tests/perf [7]_ for performance changes.
+
+Key cycle dates
+---------------
+
+Patches can be sent anytime.  Key cycle dates of the mm-unstable[1] and
+mm-stable[3] trees depend on the memory management subsystem maintainer.
+
+Review cadence
+--------------
+
+The DAMON maintainer does the work on the usual work hour (09:00 to 17:00,
+Mon-Fri) in PST.  The response to patches will occasionally be slow.  Do not
+hesitate to send a ping if you have not heard back within a week of sending a
+patch.
+
+
+.. [1] https://git.kernel.org/akpm/mm/h/mm-unstable
+.. [2] https://git.kernel.org/sj/h/damon/next
+.. [3] https://git.kernel.org/akpm/mm/h/mm-stable
+.. [4] https://github.com/awslabs/damon-tests/blob/master/corr/run.sh#L49
+.. [5] https://github.com/awslabs/damon-tests/blob/master/corr/tests/kunit.sh
+.. [6] https://github.com/awslabs/damon-tests/tree/master/corr
+.. [7] https://github.com/awslabs/damon-tests/tree/master/perf
_

Patches currently in -mm which might be from sj@kernel.org are

include-linux-mm-fix-release_pages_arg-kernel-doc-comment.patch
mm-damon-core-implement-damos-filter.patch
mm-damon-paddr-support-damos-filters.patch
mm-damon-reclaim-add-a-parameter-called-skip_anon-for-avoiding-anonymous-pages-reclamation.patch
docs-admin-guide-damon-reclaim-document-skip_anon-parameter.patch
mm-damon-sysfs-schemes-implement-filters-directory.patch
mm-damon-sysfs-schemes-implement-filter-directory.patch
mm-damon-sysfs-schemes-connect-filter-directory-and-filters-directory.patch
mm-damon-sysfs-schemes-implement-scheme-filters.patch
mm-damon-sysfs-schemes-implement-scheme-filters-fix.patch
mm-damon-sysfs-schemes-implement-scheme-filters-fix-fix-2.patch
selftests-damon-sysfs-test-filters-directory.patch
docs-admin-guide-mm-damon-usage-document-damos-filters-of-sysfs.patch
docs-abi-damon-document-scheme-filters-files.patch
mm-page_reporting-replace-rcu_access_pointer-with-rcu_dereference_protected.patch
mm-switch-vma_merge-split_vma-and-__split_vma-to-vma-iterator-fix.patch
maintainers-add-types-to-akpm-mm-git-trees-entries.patch
maintainers-memory-management-add-tools-vm-as-managed-files.patch
tools-vm-rename-tools-vm-to-tools-mm.patch
selftests-vm-rename-selftets-vm-to-selftests-mm.patch
selftests-vm-rename-selftets-vm-to-selftests-mm-fix.patch
docs-admin-guide-mm-numaperf-increase-depth-of-subsections.patch
docs-admin-guide-mm-numaperf-increase-depth-of-subsections-fix.patch
mm-damon-vaddr-rename-damon_young_walk_private-page_sz-to-folio_sz.patch
mm-damon-vaddr-support-folio-of-neither-hpage_pmd_size-nor-page_size.patch
mm-damon-vaddr-record-appropriate-folio-size-when-the-access-is-not-found.patch
mm-damon-paddr-rename-damon_pa_access_chk_result-page_sz-to-folio_sz.patch
mm-damon-paddr-remove-folio_sz-field-from-damon_pa_access_chk_result.patch
mm-damon-paddr-remove-damon_pa_access_chk_result-struct.patch
mm-damon-core-update-kernel-doc-comments-for-damos-action-supports-of-each-damon-operations-set.patch
mm-damon-core-update-kernel-doc-comments-for-damos-filters-supports-of-each-damon-operations-set.patch
docs-mm-damon-index-mention-damos-on-the-intro.patch
docs-admin-guide-mm-damon-usage-update-damos-actions-filters-supports-of-each-damon-operations-set.patch
docs-mm-damon-add-a-maintainer-profile-for-damon.patch
maintainers-damon-link-maintainer-profile-git-trees-and-website.patch
selftests-damon-sysfs-hide-expected-write-failures.patch
selftests-damon-debugfs_rm_non_contexts-hide-expected-write-error-messages.patch
scripts-spelling-add-a-few-more-typos.patch


^ permalink raw reply	[relevance 5%]

* [PATCH v2 1/1] MAINTAINERS: Add entries for NXP(Freescale) eDMA drivers
@ 2023-08-24 16:39  5%   ` Frank Li
  0 siblings, 0 replies; 200+ results
From: Frank Li @ 2023-08-24 16:39 UTC (permalink / raw)
  To: festevam
  Cc: Frank.Li, clin, conor+dt, devicetree, eagle.zhou, imx, joy.zou,
	kernel, krzysztof.kozlowski+dt, leoyang.li, linux-arm-kernel,
	linux-imx, linux-kernel, pierre.gondois, robh+dt, s.hauer,
	shawnguo, shenwei.wang, sherry.sun

Add the MAINTAINERS entries for NXP(Freescale) eDMA drivers

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---

Notes:
    Change from v1 to v2
    - alphabetical order

 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 23eafda02056..fbab3c404eb9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8215,6 +8215,14 @@ S:	Maintained
 F:	drivers/mmc/host/sdhci-esdhc-mcf.c
 F:	include/linux/platform_data/mmc-esdhc-mcf.h
 
+FREESCALE eDMA DRIVER
+M:	Frank Li <Frank.Li@nxp.com>
+L:	imx@lists.linux.dev
+L:	dmaengine@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/dma/fsl,edma.yaml
+F:	drivers/dma/fsl-edma*.*
+
 FREESCALE DIU FRAMEBUFFER DRIVER
 M:	Timur Tabi <timur@kernel.org>
 L:	linux-fbdev@vger.kernel.org
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v2 2/5] tsm: Introduce a shared ABI for attestation reports
  @ 2023-08-14  7:43  5% ` Dan Williams
  0 siblings, 0 replies; 200+ results
From: Dan Williams @ 2023-08-14  7:43 UTC (permalink / raw)
  To: linux-coco
  Cc: Kuppuswamy Sathyanarayanan, Dionna Amalie Glaze, James Bottomley,
	Peter Gonda, Greg Kroah-Hartman, Samuel Ortiz, peterz, x86,
	linux-kernel

One of the common operations of a TSM (Trusted Security Module) is to
provide a way for a TVM (confidential computing guest execution
environment) to take a measurement of its launch state, sign it and
submit it to a verifying party. Upon successful attestation that
verifies the integrity of the TVM additional secrets may be deployed.
The concept is common across TSMs, but the implementations are
unfortunately vendor specific. While the industry grapples with a common
definition of this attestation format [1], Linux need not make this
problem worse by defining a new ABI per TSM that wants to perform a
similar operation. The current momentum has been to invent new ioctl-ABI
per TSM per function which at best is an abdication of the kernel's
responsibility to make common infrastructure concepts share common ABI.

The proposal, targeted to conceptually work with TDX, SEV, COVE if not
more, is to define a sysfs interface to retrieve the TSM-specific blob.

    echo $hex_encoded_userdata_plus_nonce > /sys/class/tsm/tsm0/inhex
    hexdump /sys/class/tsm/tsm0/outblob

This approach later allows for the standardization of the attestation
blob format without needing to change the Linux ABI. Until then, the
format of 'outblob' is determined by the parent device for 'tsm0'.

The expectation is that this is a boot time exchange that need not be
regenerated, making it amenable to a sysfs interface. In case userspace
does try to generate multiple attestation reports it includes conflict
detection so userspace can be sure no other thread changed the
parameters from its last configuration step to the blob retrieval.

TSM specific options are encoded as 'extra' attributes on the TSM device
with the expectation that vendors reuse the same options for similar
concepts. The current options are defined by SEV-SNP's need for a
'privilege level' concept (VMPL), and the option to retrieve a
certificate chain in addition to the attestation report ("extended"
format).

Link: http://lore.kernel.org/r/64961c3baf8ce_142af829436@dwillia2-xfh.jf.intel.com.notmuch [1]
Cc: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Cc: Dionna Amalie Glaze <dionnaglaze@google.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Peter Gonda <pgonda@google.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Samuel Ortiz <sameo@rivosinc.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 Documentation/ABI/testing/sysfs-class-tsm |   47 +++++
 MAINTAINERS                               |    8 +
 drivers/virt/coco/Kconfig                 |    4 
 drivers/virt/coco/Makefile                |    1 
 drivers/virt/coco/tdx-guest/Kconfig       |    1 
 drivers/virt/coco/tsm.c                   |  290 +++++++++++++++++++++++++++++
 include/linux/tsm.h                       |   45 +++++
 7 files changed, 396 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-tsm
 create mode 100644 drivers/virt/coco/tsm.c
 create mode 100644 include/linux/tsm.h

diff --git a/Documentation/ABI/testing/sysfs-class-tsm b/Documentation/ABI/testing/sysfs-class-tsm
new file mode 100644
index 000000000000..37017bde626d
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-tsm
@@ -0,0 +1,47 @@
+What:		/sys/class/tsm/tsm0/inhex
+Date:		August, 2023
+KernelVersion:	v6.6
+Contact:	linux-cxl@vger.kernel.org
+Description:
+		(RW) Hex encoded userdata to be included in the attestation
+		report. For replay protection this should include a nonce, but
+		the kernel does not place any restrictions on the content.
+
+What:		/sys/class/tsm/tsm0/outblob
+Date:		August, 2023
+KernelVersion:	v6.6
+Contact:	linux-cxl@vger.kernel.org
+Description:
+		(RO) Binary attestation report generated from @inhex translated
+		to binary and any options. The format of the report is vendor
+		specific and determined by the parent device of 'tsm0'.
+
+What:		/sys/class/tsm/tsm0/generation
+Date:		August, 2023
+KernelVersion:	v6.6
+Contact:	linux-cxl@vger.kernel.org
+Description:
+		(RO) The value in this attribute increments each time @inhex or
+		any option is written. Userspace can detect conflicts by
+		checking generation before writing to any attribute and making
+		sure the number of writes matches expectations after reading
+		@outblob.
+
+What:		/sys/class/tsm/tsm0/privlevel
+Date:		August, 2023
+KernelVersion:	v6.6
+Contact:	linux-cxl@vger.kernel.org
+Description:
+		(RW) If a TSM implementation supports the concept of attestation
+		reports for TVMs running at different privilege levels, like
+		SEV-SNP "VMPL", specify the privilege level via this attribute.
+
+What:		/sys/class/tsm/tsm0/format
+Date:		August, 2023
+KernelVersion:	v6.6
+Contact:	linux-cxl@vger.kernel.org
+Description:
+		(RW) If a TSM implementation supports the concept of attestation
+		reports with "extended" contents, like SEV-SNP extended reports
+		with certificate chains, specify "extended" vs "default" via
+		this attribute.
diff --git a/MAINTAINERS b/MAINTAINERS
index 3be1bdfe8ecc..97f74d344c8a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21625,6 +21625,14 @@ W:	https://github.com/srcres258/linux-doc
 T:	git git://github.com/srcres258/linux-doc.git doc-zh-tw
 F:	Documentation/translations/zh_TW/
 
+TRUSTED SECURITY MODULE (TSM) ATTESTATION REPORTS
+M:	Dan Williams <dan.j.williams@intel.com>
+L:	linux-coco@lists.linux.dev
+S:	Maintained
+F:	Documentation/ABI/testing/sysfs-class-tsm
+F:	drivers/virt/coco/tsm.c
+F:	include/linux/tsm.h
+
 TTY LAYER
 M:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 M:	Jiri Slaby <jirislaby@kernel.org>
diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig
index fc5c64f04c4a..d92f07019f38 100644
--- a/drivers/virt/coco/Kconfig
+++ b/drivers/virt/coco/Kconfig
@@ -2,6 +2,10 @@
 #
 # Confidential computing related collateral
 #
+
+config TSM_REPORTS
+	tristate
+
 source "drivers/virt/coco/efi_secret/Kconfig"
 
 source "drivers/virt/coco/sev-guest/Kconfig"
diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile
index 55302ef719ad..18c1aba5edb7 100644
--- a/drivers/virt/coco/Makefile
+++ b/drivers/virt/coco/Makefile
@@ -2,6 +2,7 @@
 #
 # Confidential computing related collateral
 #
+obj-$(CONFIG_TSM_REPORTS)	+= tsm.o
 obj-$(CONFIG_EFI_SECRET)	+= efi_secret/
 obj-$(CONFIG_SEV_GUEST)		+= sev-guest/
 obj-$(CONFIG_INTEL_TDX_GUEST)	+= tdx-guest/
diff --git a/drivers/virt/coco/tdx-guest/Kconfig b/drivers/virt/coco/tdx-guest/Kconfig
index 14246fc2fb02..22dd59e19431 100644
--- a/drivers/virt/coco/tdx-guest/Kconfig
+++ b/drivers/virt/coco/tdx-guest/Kconfig
@@ -1,6 +1,7 @@
 config TDX_GUEST_DRIVER
 	tristate "TDX Guest driver"
 	depends on INTEL_TDX_GUEST
+	select TSM_REPORTS
 	help
 	  The driver provides userspace interface to communicate with
 	  the TDX module to request the TDX guest details like attestation
diff --git a/drivers/virt/coco/tsm.c b/drivers/virt/coco/tsm.c
new file mode 100644
index 000000000000..1bf2ee82eb94
--- /dev/null
+++ b/drivers/virt/coco/tsm.c
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2023 Intel Corporation. All rights reserved. */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/tsm.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/rwsem.h>
+#include <linux/device.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/cleanup.h>
+
+struct class *tsm_class;
+static struct tsm_provider {
+	const struct tsm_ops *ops;
+	struct device *dev;
+} provider;
+static DECLARE_RWSEM(tsm_rwsem);
+
+/**
+ * DOC: Trusted Security Module (TSM) Attestation Report Interface
+ *
+ * The TSM report interface is a common provider of blobs that facilitate
+ * attestation of a TVM (confidential computing guest) by an attestation
+ * service. A TSM report combines a user-defined blob (likely a public-key with
+ * a nonce for a key-exchange protocol) with a signed attestation report. That
+ * combined blob is then used to obtain secrets provided by an agent that can
+ * validate the attestation report. The expectation is that this interface is
+ * invoked infrequently, likely only once at TVM boot time.
+ *
+ * The attestation report format is TSM provider specific, when / if a standard
+ * materializes that can be published instead of the vendor layout.
+ */
+
+/**
+ * struct tsm_report - track state of report generation relative to options
+ * @desc: report generation options / cached report state
+ * @outblob: generated evidence to provider to the attestation agent
+ * @outblob_len: sizeof(outblob)
+ * @write_generation: conflict detection, and report regeneration tracking
+ * @read_generation: cached report invalidation tracking
+ */
+struct tsm_report {
+	struct tsm_desc desc;
+	size_t outblob_len;
+	u8 *outblob;
+	unsigned long write_generation;
+	unsigned long read_generation;
+} tsm_report;
+
+static ssize_t privlevel_store(struct device *dev,
+			       struct device_attribute *attr, const char *buf,
+			       size_t len)
+{
+	unsigned int val;
+	int rc;
+
+	rc = kstrtouint(buf, 0, &val);
+	if (rc)
+		return rc;
+
+	guard(rwsem_write)(&tsm_rwsem);
+	if (tsm_report.desc.privlevel == val)
+		return len;
+	tsm_report.desc.privlevel = val;
+	tsm_report.write_generation++;
+
+	return len;
+}
+
+static ssize_t privlevel_show(struct device *dev, struct device_attribute *attr,
+			      char *buf)
+{
+	return sysfs_emit(buf, "%u\n", tsm_report.desc.privlevel);
+}
+
+static DEVICE_ATTR_RW(privlevel);
+
+static ssize_t format_store(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t len)
+{
+	enum tsm_format format;
+
+	if (sysfs_streq(buf, "default"))
+		format = TSM_FORMAT_DEFAULT;
+	else if (sysfs_streq(buf, "extended"))
+		format = TSM_FORMAT_EXTENDED;
+	else
+		return -EINVAL;
+
+	guard(rwsem_write)(&tsm_rwsem);
+	if (tsm_report.desc.outblob_format == format)
+		return len;
+	tsm_report.desc.outblob_format = format;
+	tsm_report.write_generation++;
+
+	return len;
+}
+
+static ssize_t format_show(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	if (tsm_report.desc.outblob_format == TSM_FORMAT_DEFAULT)
+		return sysfs_emit(buf, "default\n");
+	return sysfs_emit(buf, "extended\n");
+}
+
+static DEVICE_ATTR_RW(format);
+
+static struct attribute *tsm_extra_attributes[] = {
+	&dev_attr_format.attr,
+	&dev_attr_privlevel.attr,
+	NULL,
+};
+
+struct attribute_group tsm_extra_attribute_group = {
+	.attrs = tsm_extra_attributes,
+};
+EXPORT_SYMBOL_GPL(tsm_extra_attribute_group);
+
+/*
+ * Input is a small hex blob, rather than a writable binary attribute, so that
+ * it is conveyed atomically.
+ */
+static ssize_t inhex_store(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t len)
+{
+	u8 inblob[TSM_INBLOB_MAX];
+	size_t inblob_len;
+	int rc;
+
+	inblob_len = len;
+	if (buf[len - 1] == '\n')
+		inblob_len--;
+	if (inblob_len & 1)
+		return -EINVAL;
+	inblob_len /= 2;
+	if (inblob_len > TSM_INBLOB_MAX)
+		return -EINVAL;
+
+	rc = hex2bin(inblob, buf, inblob_len);
+	if (rc < 0)
+		return rc;
+
+	guard(rwsem_write)(&tsm_rwsem);
+	if (memcmp(tsm_report.desc.inblob, inblob, inblob_len) == 0)
+		return len;
+	memcpy(tsm_report.desc.inblob, inblob, inblob_len);
+	tsm_report.desc.inblob_len = inblob_len;
+	tsm_report.write_generation++;
+
+	return len;
+}
+
+static ssize_t inhex_show(struct device *dev, struct device_attribute *attr,
+			  char *buf)
+{
+	char *end;
+
+	guard(rwsem_read)(&tsm_rwsem);
+	if (!tsm_report.desc.inblob_len)
+		return 0;
+	end = bin2hex(buf, tsm_report.desc.inblob, tsm_report.desc.inblob_len);
+	*end++ = '\n';
+	return end - buf;
+}
+static DEVICE_ATTR_RW(inhex);
+
+static ssize_t generation_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	guard(rwsem_read)(&tsm_rwsem);
+	return sysfs_emit(buf, "%lu\n", tsm_report.write_generation);
+}
+static DEVICE_ATTR_RO(generation);
+
+static struct attribute *tsm_attributes[] = {
+	&dev_attr_inhex.attr,
+	&dev_attr_generation.attr,
+	NULL,
+};
+
+static ssize_t outblob_read(struct file *f, struct kobject *kobj,
+			    struct bin_attribute *bin_attr, char *buf,
+			    loff_t offset, size_t count)
+{
+	guard(rwsem_read)(&tsm_rwsem);
+	if (!tsm_report.desc.inblob_len)
+		return -EINVAL;
+
+	if (!tsm_report.outblob ||
+	    tsm_report.read_generation != tsm_report.write_generation) {
+		const struct tsm_ops *ops = provider.ops;
+		size_t outblob_len;
+		u8 *outblob;
+
+		kvfree(tsm_report.outblob);
+		outblob = ops->report_new(provider.dev->parent,
+					  &tsm_report.desc, &outblob_len);
+		if (IS_ERR(outblob))
+			return PTR_ERR(outblob);
+		tsm_report.outblob_len = outblob_len;
+		tsm_report.outblob = outblob;
+		tsm_report.read_generation = tsm_report.write_generation;
+	}
+
+	return memory_read_from_buffer(buf, count, &offset,
+				       tsm_report.outblob,
+				       tsm_report.outblob_len);
+}
+static BIN_ATTR_RO(outblob, 0);
+
+static struct bin_attribute *tsm_bin_attributes[] = {
+	&bin_attr_outblob,
+	NULL,
+};
+
+struct attribute_group tsm_default_attribute_group = {
+	.bin_attrs = tsm_bin_attributes,
+	.attrs = tsm_attributes,
+};
+EXPORT_SYMBOL_GPL(tsm_default_attribute_group);
+
+static const struct attribute_group *tsm_default_attribute_groups[] = {
+	&tsm_default_attribute_group,
+	NULL,
+};
+
+int register_tsm(const struct tsm_ops *ops, struct device *parent,
+		 const struct attribute_group **groups)
+{
+	const struct tsm_ops *conflict;
+	struct device *dev;
+	int rc;
+
+	if (!parent)
+		return -EINVAL;
+
+	if (!groups)
+		groups = tsm_default_attribute_groups;
+
+	guard(rwsem_write)(&tsm_rwsem);
+	conflict = provider.ops;
+	if (conflict) {
+		pr_err("\"%s\" ops already registered\n", conflict->name);
+		return rc;
+	}
+
+	dev = device_create_with_groups(tsm_class, parent, 0, NULL, groups,
+					"tsm0");
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
+	provider.ops = ops;
+	provider.dev = dev;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(register_tsm);
+
+int unregister_tsm(const struct tsm_ops *ops)
+{
+	guard(rwsem_write)(&tsm_rwsem);
+	if (ops != provider.ops)
+		return -EBUSY;
+	provider.ops = NULL;
+	device_unregister(provider.dev);
+	provider.dev = NULL;
+	kvfree(tsm_report.outblob);
+	tsm_report.outblob = NULL;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(unregister_tsm);
+
+static int __init tsm_init(void)
+{
+	tsm_class = class_create("tsm");
+	return PTR_ERR_OR_ZERO(tsm_class);
+}
+module_init(tsm_init);
+
+static void __exit tsm_exit(void)
+{
+	class_destroy(tsm_class);
+}
+module_exit(tsm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Provide Trusted Security Module attestation reports via sysfs");
diff --git a/include/linux/tsm.h b/include/linux/tsm.h
new file mode 100644
index 000000000000..6dc2f07543b8
--- /dev/null
+++ b/include/linux/tsm.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __TSM_H
+#define __TSM_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+
+#define TSM_INBLOB_MAX 64
+
+enum tsm_format {
+	TSM_FORMAT_DEFAULT,
+	TSM_FORMAT_EXTENDED,
+};
+
+/**
+ * struct tsm_desc - option descriptor for generating tsm report blobs
+ * @privlevel: optional privilege level to associate with @outblob
+ * @inblob_len: sizeof @inblob
+ * @inblob: arbitrary input data
+ * @outblob_format: for TSMs with an "extended" format
+ */
+struct tsm_desc {
+	unsigned int privlevel;
+	size_t inblob_len;
+	u8 inblob[TSM_INBLOB_MAX];
+	enum tsm_format outblob_format;
+};
+
+/*
+ * arch specific ops, only one is expected to be registered at a time
+ * i.e. only one of SEV, TDX, COVE, etc.
+ */
+struct tsm_ops {
+	const char *name;
+	u8 *(*report_new)(struct device *dev, const struct tsm_desc *desc,
+			  size_t *outblob_len);
+};
+
+extern struct attribute_group tsm_default_attribute_group;
+extern struct attribute_group tsm_extra_attribute_group;
+
+int register_tsm(const struct tsm_ops *ops, struct device *parent,
+		 const struct attribute_group **groups);
+int unregister_tsm(const struct tsm_ops *ops);
+#endif /* __TSM_H */


^ permalink raw reply related	[relevance 5%]

* [PATCH v2 3/3] mm/damon/dbgfs: print DAMON debugfs interface deprecation message
    2023-02-10  4:48  5% ` [PATCH v2 2/3] mm/damon/Kconfig: add DAMON debugfs interface deprecation notice SeongJae Park
@ 2023-02-10  4:48  5% ` SeongJae Park
  1 sibling, 0 replies; 200+ results
From: SeongJae Park @ 2023-02-10  4:48 UTC (permalink / raw)
  To: Andrew Morton
  Cc: SeongJae Park, damon, linux-mm, linux-kernel, Jonathan Corbet

DAMON debugfs interface has announced to be deprecated after >v5.15 LTS
kernel is released.  And, v6.1.y has announced to be an LTS[1].

Though the announcement was there for a while, some people might not
noticed that so far.  Also, some users could depend on it and have
problems at  movng to the alternative (DAMON sysfs interface).

For such cases, warn DAMON debugfs interface deprecation with contacts
to ask helps when any DAMON debugfs interface file is opened.

[1] https://git.kernel.org/pub/scm/docs/kernel/website.git/commit/?id=332e9121320bc7461b2d3a79665caf153e51732c

Link: https://lkml.kernel.org/r/20230209192009.7885-4-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
 mm/damon/dbgfs.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c
index b3f454a5c682..124f0f8c97b7 100644
--- a/mm/damon/dbgfs.c
+++ b/mm/damon/dbgfs.c
@@ -20,6 +20,14 @@ static int dbgfs_nr_ctxs;
 static struct dentry **dbgfs_dirs;
 static DEFINE_MUTEX(damon_dbgfs_lock);
 
+static void damon_dbgfs_warn_deprecation(void)
+{
+	pr_warn_once("DAMON debugfs interface is deprecated, "
+		     "so users should move to DAMON_SYSFS. If you cannot, "
+		     "please report your usecase to damon@lists.linux.dev and "
+		     "linux-mm@kvack.org.\n");
+}
+
 /*
  * Returns non-empty string on success, negative error code otherwise.
  */
@@ -711,6 +719,8 @@ static ssize_t dbgfs_kdamond_pid_read(struct file *file,
 
 static int damon_dbgfs_open(struct inode *inode, struct file *file)
 {
+	damon_dbgfs_warn_deprecation();
+
 	file->private_data = inode->i_private;
 
 	return nonseekable_open(inode, file);
@@ -1039,15 +1049,24 @@ static ssize_t dbgfs_monitor_on_write(struct file *file,
 	return ret;
 }
 
+static int damon_dbgfs_static_file_open(struct inode *inode, struct file *file)
+{
+	damon_dbgfs_warn_deprecation();
+	return nonseekable_open(inode, file);
+}
+
 static const struct file_operations mk_contexts_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.write = dbgfs_mk_context_write,
 };
 
 static const struct file_operations rm_contexts_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.write = dbgfs_rm_context_write,
 };
 
 static const struct file_operations monitor_on_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.read = dbgfs_monitor_on_read,
 	.write = dbgfs_monitor_on_write,
 };
-- 
2.25.1


^ permalink raw reply related	[relevance 5%]

* [PATCH] REAMDE: Announce new mailing list
@ 2021-06-02  6:33  5% Daniel Wagner
  0 siblings, 0 replies; 200+ results
From: Daniel Wagner @ 2021-06-02  6:33 UTC (permalink / raw)
  To: connman; +Cc: Daniel Wagner

The project moved to a new mailing list hosted by the LF.
The 01.org domain does not longer host any ConnMan related
services. Drop these references also from the README.
---
 README | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/README b/README
index e911bc2d6bbd..ff98ee91a341 100644
--- a/README
+++ b/README
@@ -444,10 +444,7 @@ Information
 ===========
 
 Mailing list:
-	connman@connman.net
+	connman@lists.linux.dev
 
 For additional information about the project visit ConnMan web site:
-	https://01.org/connman
-	http://www.connman.net
-
-You can report bugs at https://01.org/jira/browse/CM
+	https://lore.kernel.org/connman/
-- 
2.31.1

^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: Update the entry for MHI bus
@ 2021-10-06  6:25  5% Manivannan Sadhasivam
  0 siblings, 0 replies; 200+ results
From: Manivannan Sadhasivam @ 2021-10-06  6:25 UTC (permalink / raw)
  To: mhi; +Cc: hemantk, bbhatt, linux-arm-msm, linux-kernel,
	Manivannan Sadhasivam

Since Hemant is not carrying out any maintainership duties let's make
him as a dedicated reviewer. Also add the new mailing lists dedicated
for MHI in subspace mailing list server.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 MAINTAINERS | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index eeb4c70b3d5b..8ae357d746c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12191,7 +12191,8 @@ F:	arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
 
 MHI BUS
 M:	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-M:	Hemant Kumar <hemantk@codeaurora.org>
+R:	Hemant Kumar <hemantk@codeaurora.org>
+L:	mhi@lists.linux.dev
 L:	linux-arm-msm@vger.kernel.org
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git
-- 
2.25.1


^ permalink raw reply related	[relevance 5%]

* [PATCH 1/3] MAINTAINERS: Update the entry for MHI bus
  @ 2021-10-16  6:57  5% ` Manivannan Sadhasivam
  0 siblings, 0 replies; 200+ results
From: Manivannan Sadhasivam @ 2021-10-16  6:57 UTC (permalink / raw)
  To: gregkh
  Cc: hemantk, bbhatt, loic.poulain, wangqing, mhi, linux-arm-msm,
	linux-kernel, Manivannan Sadhasivam

Since Hemant is not carrying out any maintainership duties let's make
him as a dedicated reviewer. Also add the new mailing lists dedicated
for MHI in subspace mailing list server.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 MAINTAINERS | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index eeb4c70b3d5b..8ae357d746c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12191,7 +12191,8 @@ F:	arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
 
 MHI BUS
 M:	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-M:	Hemant Kumar <hemantk@codeaurora.org>
+R:	Hemant Kumar <hemantk@codeaurora.org>
+L:	mhi@lists.linux.dev
 L:	linux-arm-msm@vger.kernel.org
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git
-- 
2.25.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v2] MAINTAINERS: Update the entry for MHI bus
@ 2021-10-19 13:39  5% Manivannan Sadhasivam
  0 siblings, 0 replies; 200+ results
From: Manivannan Sadhasivam @ 2021-10-19 13:39 UTC (permalink / raw)
  To: gregkh
  Cc: hemantk, bbhatt, mhi, linux-arm-msm, linux-kernel,
	Manivannan Sadhasivam

Since Hemant is not carrying out any maintainership duties let's make
him as a dedicated reviewer. Also add the new mailing lists dedicated
for MHI in subspace mailing list server.

Reviewed-by: Hemant Kumar <hemantk@codeaurora.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---

Changes in v2:

* Added Hemant's Reviewed-by tag

 MAINTAINERS | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index eeb4c70b3d5b..8ae357d746c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12191,7 +12191,8 @@ F:	arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
 
 MHI BUS
 M:	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-M:	Hemant Kumar <hemantk@codeaurora.org>
+R:	Hemant Kumar <hemantk@codeaurora.org>
+L:	mhi@lists.linux.dev
 L:	linux-arm-msm@vger.kernel.org
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git
-- 
2.25.1


^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: Add a mailing list for DAMON development
@ 2022-05-03 18:07  5% SeongJae Park
  0 siblings, 0 replies; 200+ results
From: SeongJae Park @ 2022-05-03 18:07 UTC (permalink / raw)
  To: akpm; +Cc: damon, linux-damon, linux-mm, linux-kernel, SeongJae Park

This commit adds an open mailing list for DAMON in MAINTAINERS file.

Signed-off-by: SeongJae Park <sj@kernel.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 701504ef2902..56a751fca360 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5457,6 +5457,7 @@ F:	net/ax25/sysctl_net_ax25.c
 
 DATA ACCESS MONITOR
 M:	SeongJae Park <sj@kernel.org>
+L:	damon@lists.linux.dev
 L:	linux-mm@kvack.org
 S:	Maintained
 F:	Documentation/ABI/testing/sysfs-kernel-mm-damon
-- 
2.25.1


^ permalink raw reply related	[relevance 5%]

* [merged mm-hotfixes-stable] maintainers-add-a-mailing-list-for-damon-development.patch removed from -mm tree
@ 2022-05-10  4:09  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2022-05-10  4:09 UTC (permalink / raw)
  To: mm-commits, sj, akpm


The quilt patch titled
     Subject: MAINTAINERS: add a mailing list for DAMON development
has been removed from the -mm tree.  Its filename was
     maintainers-add-a-mailing-list-for-damon-development.patch

This patch was dropped because it was merged into mm-hotfixes-stable

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: MAINTAINERS: add a mailing list for DAMON development

This commit adds an open mailing list for DAMON in MAINTAINERS file.

Link: https://lkml.kernel.org/r/20220503180741.137079-1-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 MAINTAINERS |    1 +
 1 file changed, 1 insertion(+)

--- a/MAINTAINERS~maintainers-add-a-mailing-list-for-damon-development
+++ a/MAINTAINERS
@@ -5438,6 +5438,7 @@ F:	net/ax25/sysctl_net_ax25.c
 
 DATA ACCESS MONITOR
 M:	SeongJae Park <sj@kernel.org>
+L:	damon@lists.linux.dev
 L:	linux-mm@kvack.org
 S:	Maintained
 F:	Documentation/ABI/testing/sysfs-kernel-mm-damon
_

Patches currently in -mm which might be from sj@kernel.org are



^ permalink raw reply	[relevance 5%]

* [PATCH] MAINTAINERS: add ARM/APPLE MACHINE mailing list
@ 2022-06-02 17:31  5% ` Sven Peter
  0 siblings, 0 replies; 200+ results
From: Sven Peter @ 2022-06-02 17:31 UTC (permalink / raw)
  To: Sven Peter, Hector Martin, Alyssa Rosenzweig
  Cc: linux-arm-kernel, asahi, linux-kernel

Signed-off-by: Sven Peter <sven@svenpeter.dev>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 55114e73de26..621eeb037a91 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1826,6 +1826,7 @@ ARM/APPLE MACHINE SUPPORT
 M:	Hector Martin <marcan@marcan.st>
 M:	Sven Peter <sven@svenpeter.dev>
 R:	Alyssa Rosenzweig <alyssa@rosenzweig.io>
+L:	asahi@lists.linux.dev
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 W:	https://asahilinux.org
-- 
2.25.1


^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: add ARM/APPLE MACHINE mailing list
@ 2022-06-02 17:31  5% ` Sven Peter
  0 siblings, 0 replies; 200+ results
From: Sven Peter @ 2022-06-02 17:31 UTC (permalink / raw)
  To: Sven Peter, Hector Martin, Alyssa Rosenzweig
  Cc: linux-arm-kernel, asahi, linux-kernel

Signed-off-by: Sven Peter <sven@svenpeter.dev>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 55114e73de26..621eeb037a91 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1826,6 +1826,7 @@ ARM/APPLE MACHINE SUPPORT
 M:	Hector Martin <marcan@marcan.st>
 M:	Sven Peter <sven@svenpeter.dev>
 R:	Alyssa Rosenzweig <alyssa@rosenzweig.io>
+L:	asahi@lists.linux.dev
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 W:	https://asahilinux.org
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH 1/2] MAINTAINERS: Update ocfs2-devel mailing list address
  @ 2023-06-28  1:34  5% ` Anthony Iliopoulos
  0 siblings, 0 replies; 200+ results
From: Anthony Iliopoulos @ 2023-06-28  1:34 UTC (permalink / raw)
  To: Mark Fasheh, Joel Becker, Joseph Qi; +Cc: ocfs2-devel, linux-kernel, linux-doc

The ocfs2-devel mailing list has been migrated to the kernel.org
infrastructure, update the related entry to reflect the change.

Signed-off-by: Anthony Iliopoulos <ailiop@suse.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4545d4287305..2e95a8eb924e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15969,7 +15969,7 @@ ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
 M:	Mark Fasheh <mark@fasheh.com>
 M:	Joel Becker <jlbec@evilplan.org>
 M:	Joseph Qi <joseph.qi@linux.alibaba.com>
-L:	ocfs2-devel@oss.oracle.com (moderated for non-subscribers)
+L:	ocfs2-devel@lists.linux.dev
 S:	Supported
 W:	http://ocfs2.wiki.kernel.org
 F:	Documentation/filesystems/dlmfs.rst
-- 
2.35.3


^ permalink raw reply related	[relevance 5%]

* [PATCH 1/1] MAINTAINERS: Add entries for NXP(Freescale) eDMA drivers
@ 2023-08-23 18:44  5% Frank Li
  0 siblings, 0 replies; 200+ results
From: Frank Li @ 2023-08-23 18:44 UTC (permalink / raw)
  To: vkoul
  Cc: devicetree, dmaengine, frank.li, imx, joy.zou, linux-kernel,
	peng.fan, shenwei.wang

Add the MAINTAINERS entries for NXP(Freescale) eDMA drivers

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 23eafda02056..eba417bb5ffb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8228,6 +8228,14 @@ L:	linuxppc-dev@lists.ozlabs.org
 S:	Maintained
 F:	drivers/dma/fsldma.*
 
+FREESCALE eDMA DRIVER
+M:	Frank Li <Frank.Li@nxp.com>
+L:	imx@lists.linux.dev
+L:	dmaengine@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/dma/fsl,edma.yaml
+F:	drivers/dma/fsl-edma*.*
+
 FREESCALE DSPI DRIVER
 M:	Vladimir Oltean <olteanv@gmail.com>
 L:	linux-spi@vger.kernel.org
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v2 1/1] MAINTAINERS: Add entries for NXP(Freescale) eDMA drivers
@ 2023-08-24  3:04  5% Frank Li
  0 siblings, 0 replies; 200+ results
From: Frank Li @ 2023-08-24  3:04 UTC (permalink / raw)
  To: rdunlap
  Cc: Frank.Li, devicetree, dmaengine, imx, joy.zou, linux-kernel,
	peng.fan, shenwei.wang, vkoul

Add the MAINTAINERS entries for NXP(Freescale) eDMA drivers

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---

Notes:
    Change from v1 to v2
    - alphabetical order

 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 23eafda02056..fbab3c404eb9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8215,6 +8215,14 @@ S:	Maintained
 F:	drivers/mmc/host/sdhci-esdhc-mcf.c
 F:	include/linux/platform_data/mmc-esdhc-mcf.h
 
+FREESCALE eDMA DRIVER
+M:	Frank Li <Frank.Li@nxp.com>
+L:	imx@lists.linux.dev
+L:	dmaengine@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/dma/fsl,edma.yaml
+F:	drivers/dma/fsl-edma*.*
+
 FREESCALE DIU FRAMEBUFFER DRIVER
 M:	Timur Tabi <timur@kernel.org>
 L:	linux-fbdev@vger.kernel.org
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v3 1/1] MAINTAINERS: Add entries for NXP(Freescale) eDMA drivers
@ 2023-08-24 14:58  5% Frank Li
  0 siblings, 0 replies; 200+ results
From: Frank Li @ 2023-08-24 14:58 UTC (permalink / raw)
  To: rdunlap
  Cc: Frank.Li, dmaengine, imx, joy.zou, linux-kernel, peng.fan,
	shenwei.wang, vkoul

Add the MAINTAINERS entries for NXP(Freescale) eDMA drivers

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---

Notes:
    Change from v2 to v3
    - Again, fixed order
    
    Change from v1 to v2
    - alphabetical order

 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 23eafda02056..c1c7a9ae244f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8236,6 +8236,14 @@ F:	Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt
 F:	drivers/spi/spi-fsl-dspi.c
 F:	include/linux/spi/spi-fsl-dspi.h
 
+FREESCALE eDMA DRIVER
+M:	Frank Li <Frank.Li@nxp.com>
+L:	imx@lists.linux.dev
+L:	dmaengine@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/dma/fsl,edma.yaml
+F:	drivers/dma/fsl-edma*.*
+
 FREESCALE ENETC ETHERNET DRIVERS
 M:	Claudiu Manoil <claudiu.manoil@nxp.com>
 M:	Vladimir Oltean <vladimir.oltean@nxp.com>
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH 1/2] MAINTAINERS: Update gfs2 mailing list
@ 2023-08-31  9:57  5% ` Andrew Price
  0 siblings, 0 replies; 200+ results
From: Andrew Price @ 2023-08-31  9:57 UTC (permalink / raw)
  To: agruenba, rpeterso, teigland, ccaulfie; +Cc: cluster-devel, gfs2

Signed-off-by: Andrew Price <anprice@redhat.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4b8d634f3a4e..caae31fb9741 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8725,7 +8725,7 @@ F:	scripts/get_maintainer.pl
 GFS2 FILE SYSTEM
 M:	Bob Peterson <rpeterso@redhat.com>
 M:	Andreas Gruenbacher <agruenba@redhat.com>
-L:	cluster-devel@redhat.com
+L:	gfs2@lists.linux.dev
 S:	Supported
 B:	https://bugzilla.kernel.org/enter_bug.cgi?product=File%20System&component=gfs2
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git
-- 
2.41.0


^ permalink raw reply related	[relevance 5%]

* [PATCH 2/2] MAINTAINERS: Update dlm mailing list
  2023-08-31  9:57  5% ` Andrew Price
@ 2023-08-31  9:57  5%   ` Andrew Price
  -1 siblings, 0 replies; 200+ results
From: Andrew Price @ 2023-08-31  9:57 UTC (permalink / raw)
  To: agruenba, rpeterso, teigland, ccaulfie; +Cc: cluster-devel, gfs2

The new gfs2@ list will also be used for dlm development.

Signed-off-by: Andrew Price <anprice@redhat.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index caae31fb9741..946fcf6c8d77 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6093,7 +6093,7 @@ F:	include/video/udlfb.h
 DISTRIBUTED LOCK MANAGER (DLM)
 M:	Christine Caulfield <ccaulfie@redhat.com>
 M:	David Teigland <teigland@redhat.com>
-L:	cluster-devel@redhat.com
+L:	gfs2@lists.linux.dev
 S:	Supported
 W:	http://sources.redhat.com/cluster/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git
-- 
2.41.0


^ permalink raw reply related	[relevance 5%]

* [Cluster-devel] [PATCH 2/2] MAINTAINERS: Update dlm mailing list
@ 2023-08-31  9:57  5%   ` Andrew Price
  0 siblings, 0 replies; 200+ results
From: Andrew Price @ 2023-08-31  9:57 UTC (permalink / raw)
  To: agruenba, rpeterso, teigland, ccaulfie; +Cc: cluster-devel, gfs2

The new gfs2@ list will also be used for dlm development.

Signed-off-by: Andrew Price <anprice@redhat.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index caae31fb9741..946fcf6c8d77 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6093,7 +6093,7 @@ F:	include/video/udlfb.h
 DISTRIBUTED LOCK MANAGER (DLM)
 M:	Christine Caulfield <ccaulfie@redhat.com>
 M:	David Teigland <teigland@redhat.com>
-L:	cluster-devel@redhat.com
+L:	gfs2@lists.linux.dev
 S:	Supported
 W:	http://sources.redhat.com/cluster/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git
-- 
2.41.0


^ permalink raw reply related	[relevance 5%]

* [Cluster-devel] [PATCH 1/2] MAINTAINERS: Update gfs2 mailing list
@ 2023-08-31  9:57  5% ` Andrew Price
  0 siblings, 0 replies; 200+ results
From: Andrew Price @ 2023-08-31  9:57 UTC (permalink / raw)
  To: agruenba, rpeterso, teigland, ccaulfie; +Cc: cluster-devel, gfs2

Signed-off-by: Andrew Price <anprice@redhat.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4b8d634f3a4e..caae31fb9741 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8725,7 +8725,7 @@ F:	scripts/get_maintainer.pl
 GFS2 FILE SYSTEM
 M:	Bob Peterson <rpeterso@redhat.com>
 M:	Andreas Gruenbacher <agruenba@redhat.com>
-L:	cluster-devel@redhat.com
+L:	gfs2@lists.linux.dev
 S:	Supported
 B:	https://bugzilla.kernel.org/enter_bug.cgi?product=File%20System&component=gfs2
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git
-- 
2.41.0


^ permalink raw reply related	[relevance 5%]

* [PATCH resent 1/1] MAINTAINERS: Add entries for NXP(Freescale) eDMA drivers
@ 2023-10-04 14:32  5% Frank Li
  0 siblings, 0 replies; 200+ results
From: Frank Li @ 2023-10-04 14:32 UTC (permalink / raw)
  To: vkoul
  Cc: Frank.li, dmaengine, imx, joy.zou, linux-kernel, peng.fan,
	rdunlap, shenwei.wang

Add the MAINTAINERS entries for NXP(Freescale) eDMA drivers

Acked-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---

Notes:
    Change from v2 to v3
    - Again, fixed order
    
    Change from v1 to v2
    - alphabetical order
    
    Change from v1 to v2
    - alphabetical order

 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 23eafda02056..c1c7a9ae244f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8236,6 +8236,14 @@ F:	Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt
 F:	drivers/spi/spi-fsl-dspi.c
 F:	include/linux/spi/spi-fsl-dspi.h
 
+FREESCALE eDMA DRIVER
+M:	Frank Li <Frank.Li@nxp.com>
+L:	imx@lists.linux.dev
+L:	dmaengine@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/dma/fsl,edma.yaml
+F:	drivers/dma/fsl-edma*.*
+
 FREESCALE ENETC ETHERNET DRIVERS
 M:	Claudiu Manoil <claudiu.manoil@nxp.com>
 M:	Vladimir Oltean <vladimir.oltean@nxp.com>
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: update virtio-fs mailing list address
@ 2023-11-11  0:49  5% Stefan Hajnoczi
  0 siblings, 0 replies; 200+ results
From: Stefan Hajnoczi @ 2023-11-11  0:49 UTC (permalink / raw)
  To: qemu-devel
  Cc: Stefan Hajnoczi, Philippe Mathieu-Daudé, Vivek Goyal,
	German Maglione, Hanna Czenczek

The old virtio-fs mailing list address is no longer in use. Switch to
the new mailing list address.

Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: German Maglione <gmaglione@redhat.com>
Cc: Hanna Czenczek <hreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index e73a3ff544..c52df9f76c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2241,7 +2241,7 @@ M: Stefan Hajnoczi <stefanha@redhat.com>
 S: Supported
 F: hw/virtio/vhost-user-fs*
 F: include/hw/virtio/vhost-user-fs.h
-L: virtio-fs@redhat.com
+L: virtio-fs@lists.linux.dev
 
 virtio-input
 M: Gerd Hoffmann <kraxel@redhat.com>
-- 
2.41.0



^ permalink raw reply related	[relevance 5%]

* [PULL 5/5] MAINTAINERS: update virtio-fs mailing list address
  @ 2023-11-13 18:17  5% ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 200+ results
From: Philippe Mathieu-Daudé @ 2023-11-13 18:17 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-s390x, Stefan Hajnoczi, Philippe Mathieu-Daudé,
	Vivek Goyal, German Maglione, Hanna Czenczek

From: Stefan Hajnoczi <stefanha@redhat.com>

The old virtio-fs mailing list address is no longer in use. Switch to
the new mailing list address.

Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: German Maglione <gmaglione@redhat.com>
Cc: Hanna Czenczek <hreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: German Maglione <gmaglione@redhat.com>
Message-ID: <20231111004920.148348-1-stefanha@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index e73a3ff544..c52df9f76c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2241,7 +2241,7 @@ M: Stefan Hajnoczi <stefanha@redhat.com>
 S: Supported
 F: hw/virtio/vhost-user-fs*
 F: include/hw/virtio/vhost-user-fs.h
-L: virtio-fs@redhat.com
+L: virtio-fs@lists.linux.dev
 
 virtio-input
 M: Gerd Hoffmann <kraxel@redhat.com>
-- 
2.41.0



^ permalink raw reply related	[relevance 5%]

* [PATCH 1/1] MAINTAINERS: add mail list for freescale imx ddr pmu driver
@ 2024-01-29 16:42  5% ` Frank Li
  0 siblings, 0 replies; 200+ results
From: Frank Li @ 2024-01-29 16:42 UTC (permalink / raw)
  To: imx, well, linux-arm-kernel, open list

add mail list for freescale imx ddr pmu driver.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 72d27e3ad8bca..21894f83a501b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8508,6 +8508,7 @@ F:	drivers/video/fbdev/imxfb.c
 FREESCALE IMX DDR PMU DRIVER
 M:	Frank Li <Frank.li@nxp.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:	imx@lists.linux.dev
 S:	Maintained
 F:	Documentation/admin-guide/perf/imx-ddr.rst
 F:	Documentation/devicetree/bindings/perf/fsl-imx-ddr.yaml
-- 
2.34.1


^ permalink raw reply related	[relevance 5%]

* [PATCH 1/1] MAINTAINERS: add mail list for freescale imx ddr pmu driver
@ 2024-01-29 16:42  5% ` Frank Li
  0 siblings, 0 replies; 200+ results
From: Frank Li @ 2024-01-29 16:42 UTC (permalink / raw)
  To: imx, well, linux-arm-kernel, open list

add mail list for freescale imx ddr pmu driver.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 72d27e3ad8bca..21894f83a501b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8508,6 +8508,7 @@ F:	drivers/video/fbdev/imxfb.c
 FREESCALE IMX DDR PMU DRIVER
 M:	Frank Li <Frank.li@nxp.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:	imx@lists.linux.dev
 S:	Maintained
 F:	Documentation/admin-guide/perf/imx-ddr.rst
 F:	Documentation/devicetree/bindings/perf/fsl-imx-ddr.yaml
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: apply maintainer role of Intel vDPA driver
@ 2024-02-27 14:45  5% Zhu Lingshan
  0 siblings, 0 replies; 200+ results
From: Zhu Lingshan @ 2024-02-27 14:45 UTC (permalink / raw)
  To: jasowang, mst; +Cc: virtualization, Zhu Lingshan

This commit applies maintainer role of Intel vDPA
driver for myself.

I am the author of this driver and have been contributing to
it for long time, I would like to help this solution evolve
in future.

This driver is still under virito maintenance.

Signed-off-by: Zhu Lingshan <lingshan.zhu@intel.com>
---
 MAINTAINERS | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2ecaaec6a6bf..128ec843eb19 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10365,8 +10365,10 @@ F:	include/net/nl802154.h
 F:	net/ieee802154/
 F:	net/mac802154/
 
-IFCVF VIRTIO DATA PATH ACCELERATOR
-R:	Zhu Lingshan <lingshan.zhu@intel.com>
+Intel VIRTIO DATA PATH ACCELERATOR
+M:	Zhu Lingshan <lingshan.zhu@intel.com>
+L:	virtualization@lists.linux.dev
+S:	Supported
 F:	drivers/vdpa/ifcvf/
 
 IFE PROTOCOL
-- 
2.39.3


^ permalink raw reply related	[relevance 5%]

* [PATCH 19/19] connman: submit 0002-resolve-musl-does-not-implement-res_ninit.patch upstream
  @ 2024-04-19 12:19  5% ` Alexander Kanavin
  0 siblings, 0 replies; 200+ results
From: Alexander Kanavin @ 2024-04-19 12:19 UTC (permalink / raw)
  To: openembedded-core; +Cc: Alexander Kanavin

Signed-off-by: Alexander Kanavin <alex@linutronix.de>
---
 .../0002-resolve-musl-does-not-implement-res_ninit.patch        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta/recipes-connectivity/connman/connman/0002-resolve-musl-does-not-implement-res_ninit.patch b/meta/recipes-connectivity/connman/connman/0002-resolve-musl-does-not-implement-res_ninit.patch
index 71efd9035e9..9e2cc34995a 100644
--- a/meta/recipes-connectivity/connman/connman/0002-resolve-musl-does-not-implement-res_ninit.patch
+++ b/meta/recipes-connectivity/connman/connman/0002-resolve-musl-does-not-implement-res_ninit.patch
@@ -21,7 +21,7 @@ The portion of the patch that implements a fallback is ported from
 Alpine Linux:
 http://git.alpinelinux.org/cgit/aports/plain/testing/connman/libresolv.patch
 
-Upstream-Status: Pending
+Upstream-Status: Submitted [to connman@lists.linux.dev,marcel@holtmann.org]
 
 Signed-off-by: Khem Raj <raj.khem@gmail.com>
 ---
-- 
2.39.2



^ permalink raw reply related	[relevance 5%]

* [PATCH net] MAINTAINERS: Update MPTCP maintainer list and CREDITS
@ 2023-01-20 23:11  5% Mat Martineau
  0 siblings, 0 replies; 200+ results
From: Mat Martineau @ 2023-01-20 23:11 UTC (permalink / raw)
  To: netdev; +Cc: Mat Martineau, davem, kuba, pabeni, edumazet, matthieu.baerts,
	mptcp

My responsibilities at Intel have changed, so I'm handing off exclusive
MPTCP subsystem maintainer duties to Matthieu. It has been a privilege
to see MPTCP through its initial upstreaming and first few years in the
upstream kernel!

Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
---
 CREDITS     | 7 +++++++
 MAINTAINERS | 1 -
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/CREDITS b/CREDITS
index 4e302a459ddf..acac06b6563e 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2489,6 +2489,13 @@ D: XF86_Mach8
 D: XF86_8514
 D: cfdisk (curses based disk partitioning program)
 
+N: Mat Martineau
+E: mat@martineau.name
+D: MPTCP subsystem co-maintainer 2020-2023
+D: Keyctl restricted keyring and Diffie-Hellman UAPI
+D: Bluetooth L2CAP ERTM mode and AMP
+S: USA
+
 N: John S. Marvin
 E: jsm@fc.hp.com
 D: PA-RISC port
diff --git a/MAINTAINERS b/MAINTAINERS
index f8ef124a941b..fdc81ee6df1f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14633,7 +14633,6 @@ F:	net/netfilter/xt_SECMARK.c
 F:	net/netlabel/
 
 NETWORKING [MPTCP]
-M:	Mat Martineau <mathew.j.martineau@linux.intel.com>
 M:	Matthieu Baerts <matthieu.baerts@tessares.net>
 L:	netdev@vger.kernel.org
 L:	mptcp@lists.linux.dev
-- 
2.39.1


^ permalink raw reply related	[relevance 5%]

* [PATCH mptcp-net] MAINTAINERS: Update MPTCP maintainer list and CREDITS
@ 2023-01-19 22:44  5% Mat Martineau
  0 siblings, 0 replies; 200+ results
From: Mat Martineau @ 2023-01-19 22:44 UTC (permalink / raw)
  To: mptcp, matthieu.baerts; +Cc: Mat Martineau

My responsibilities at Intel have changed, so I'm handing off exclusive
MPTCP subsystem maintainer duties to Matthieu. It has been a privilege
to see MPTCP through its initial upstreaming and first few years in the
upstream kernel!

Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
---

Hi Matthieu -

Hoping you can tag this (not sure if signoff or Acked-by is best?)
before I send to netdev.

Thanks,

Mat


---
 CREDITS     | 7 +++++++
 MAINTAINERS | 1 -
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/CREDITS b/CREDITS
index 4e302a459ddf..acac06b6563e 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2489,6 +2489,13 @@ D: XF86_Mach8
 D: XF86_8514
 D: cfdisk (curses based disk partitioning program)
 
+N: Mat Martineau
+E: mat@martineau.name
+D: MPTCP subsystem co-maintainer 2020-2023
+D: Keyctl restricted keyring and Diffie-Hellman UAPI
+D: Bluetooth L2CAP ERTM mode and AMP
+S: USA
+
 N: John S. Marvin
 E: jsm@fc.hp.com
 D: PA-RISC port
diff --git a/MAINTAINERS b/MAINTAINERS
index 180c18f936b7..b166dec1ffc3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14633,7 +14633,6 @@ F:	net/netfilter/xt_SECMARK.c
 F:	net/netlabel/
 
 NETWORKING [MPTCP]
-M:	Mat Martineau <mathew.j.martineau@linux.intel.com>
 M:	Matthieu Baerts <matthieu.baerts@tessares.net>
 L:	netdev@vger.kernel.org
 L:	mptcp@lists.linux.dev
-- 
2.39.1


^ permalink raw reply related	[relevance 5%]

* 50% OFF din pret. ntfs3@lists.linux.dev
@ 2022-12-07 14:47  5% Publicitate digitala in mall-uri
  0 siblings, 0 replies; 200+ results
From: Publicitate digitala in mall-uri @ 2022-12-07 14:47 UTC (permalink / raw)
  To: ntfs3


[-- Attachment #1.1: Type: text/plain, Size: 4773 bytes --]





0771 303 303
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781823&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=tel%3A0771303303&_ntm_sentIdx=1ed763df-ff73-60e4-a532-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397693&_ntm_usr=15532&_ntm_sig=e60a9d350d0b1485b5b2311e9bf00f74488869325b6fd883e82297a4db4d81c9)
office@ekogroup.ro
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781823&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=mailto%3Aoffice%40ekogroup.ro&_ntm_sentIdx=1ed763df-ff73-60e4-a532-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397694&_ntm_usr=15532&_ntm_sig=1010cbf9756c066a1f8d36259a060acb06a8e5967a6aca8a39f0e38ba723b7cb)




Oferta digitala
DISCOUNT 50% din pretul chiriei TIMP DE 3 LUNI daca se semneaza si se achita 
contracte înaintea inceperii campaniilor!
  Primul totem la VERANDA mall dintr o serie de 5000 buc la nivel 
national(toate centrele comerciale din ROMANIA) în urmatorii 2 ani.   
Totemurile apartin companieiekogroup.ro 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781823&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=http%3A%2F%2Fekogroup.ro%2F&_ntm_sentIdx=1ed763df-ff73-60e4-a532-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397695&_ntm_usr=15532&_ntm_sig=d9d7445c2baf1de6d1c2a4bb027d7b399bbbd5e013af57b75ed6a7f43a3f3077)
(nu suntem revanzatori de servicii)   Putem facilita vanzarea media kit-urilor 
indoor si outdoor în toate centrele comerciale la preturi avantajoase.   
Preturile sunt negociabile în functie de perioada.   Urmatoarele proiecte pana 
la decembrie 2022- martie 2023:   Mall Veranda: - 7 totem toate etajele - 4 tv 
uri 86 inch food court - exclusivitate vanzare media kit indoor-outdoor  Data 
incepere campanii: 20 decembrie 2022 https://youtube.com/shorts/N0_m1WJUrYE 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781823&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=https%3A%2F%2Fyoutube.com%2Fshorts%2FN0_m1WJUrYE&_ntm_sentIdx=1ed763df-ff73-60e4-a532-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397696&_ntm_usr=15532&_ntm_sig=dc016627b410082b4373225c9f8df5c14b09c08408b5cec634b445bcf9380183)
  Cineplexx Baneasa: - videowall intrare cineplexx(vis a vis de Carturesti) 
https://drive.google.com/file/d/18tbAZ5KpOojmfyIK440n7wsSxF6k4W4m/view 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781823&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=https%3A%2F%2Fdrive.google.com%2Ffile%2Fd%2F18tbAZ5KpOojmfyIK440n7wsSxF6k4W4m%2Fview&_ntm_sentIdx=1ed763df-ff73-60e4-a532-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397697&_ntm_usr=15532&_ntm_sig=172dfdc42d4ba694c3c286c2855d21349da81044909d797bcd64cd315618015e)
- 2 totem 2300mm x 1230mm, 86 inch FOAYER Cineplexx Baneasa, PARTER - 1 totem 
subsol, vis a vis de sala VIP Data începere campanii: 1 martie 2023   Cineplexx 
TITAN: - 1 totem 98 inch intrare Cinplexx partea stânga - 2 totem 86 inch 
FOAYER langa stalpii de rezistenta - 1 totem 86 inch langa casele de 
bilete/popcorn - 2 totem 98 inch în proximitatea Foayerului salilor de cinema 
Data începere campanii: 15 ianuarie 2023   Reteaua KAUFLAND: - 1 totem 86 inch 
fata simpla la fiecare intrare/iesire KAUFLAND Bucuresti (Total avem 18 
locaÈ›ii, câte un totem pe fiecare locaÈ›ie) Data începere campanii: 1 martie 
2023 
 





Solicita oferta
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781823&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=mailto%3Aoffice%40ekogroup.ro&_ntm_sentIdx=1ed763df-ff73-60e4-a532-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397694&_ntm_usr=15532&_ntm_sig=1010cbf9756c066a1f8d36259a060acb06a8e5967a6aca8a39f0e38ba723b7cb)



 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781823&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=https%3A%2F%2Fwww.youtube.com%2Fshorts%2FN0_m1WJUrYE&_ntm_sentIdx=1ed763df-ff73-60e4-a532-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397698&_ntm_usr=15532&_ntm_sig=cebb7fd85bbab62f3e668adffecf7f90aa6565b14e3b27a630563eebb3b1d302)




Solicita oferta
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781823&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=mailto%3Aoffice%40ekogroup.ro&_ntm_sentIdx=1ed763df-ff73-60e4-a532-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397694&_ntm_usr=15532&_ntm_sig=1010cbf9756c066a1f8d36259a060acb06a8e5967a6aca8a39f0e38ba723b7cb)




În conformitate cu prevederile Regulamentului (UE) 2016/679 din 27 aprilie 
2016 (GDPR), vă informăm că datele dumneavoastră cu caracter personal sunt 
prelucrate doar de către societatea noastră și au ca unic scop transmiterea de 
informații despre produsele și serviciile noastre. Vă puteți exercita 
drepturile de acces, de anulare.

Dezabonare  
(https://tracking3.360nrs.net/unsubscribe/mailing/15532/281781823/565323/bd7233f857/null/)



[-- Attachment #1.2: Type: text/html, Size: 30214 bytes --]

^ permalink raw reply	[relevance 5%]

* [PATCH 3/3] mm/damon/dbgfs: print DAMON debugfs interface deprecation message
    2023-02-09 19:20  5% ` [PATCH 2/3] mm/damon/Kconfig: add DAMON debugfs interface deprecation notice SeongJae Park
@ 2023-02-09 19:20  5% ` SeongJae Park
  1 sibling, 0 replies; 200+ results
From: SeongJae Park @ 2023-02-09 19:20 UTC (permalink / raw)
  To: Andrew Morton; +Cc: SeongJae Park, damon, linux-mm, linux-kernel

DAMON debugfs interface has announced to be deprecated after >v5.15 LTS
kernel is released.  And, v6.1.y has announced to be an LTS[1].

Though the announcement was there for a while, some people might not
noticed that so far.  Also, some users could depend on it and have
problems at  movng to the alternative (DAMON sysfs interface).

For such cases, warn DAMON debugfs interface deprecation with contacts
to ask helps when any DAMON debugfs interface file is opened.

[1] https://git.kernel.org/pub/scm/docs/kernel/website.git/commit/?id=332e9121320bc7461b2d3a79665caf153e51732c

Signed-off-by: SeongJae Park <sj@kernel.org>
---
 mm/damon/dbgfs.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c
index b3f454a5c682..e551a20b35e3 100644
--- a/mm/damon/dbgfs.c
+++ b/mm/damon/dbgfs.c
@@ -20,6 +20,11 @@ static int dbgfs_nr_ctxs;
 static struct dentry **dbgfs_dirs;
 static DEFINE_MUTEX(damon_dbgfs_lock);
 
+static void damon_dbgfs_warn_deprecation(void)
+{
+	pr_warn_once("DAMON debugfs interface is deprecated, so users should move to the sysfs interface (DAMON_SYSFS).  If you depend on this and cannot move, please report your usecase to damon@lists.linux.dev and linux-mm@kvack.org.\n");
+}
+
 /*
  * Returns non-empty string on success, negative error code otherwise.
  */
@@ -711,6 +716,8 @@ static ssize_t dbgfs_kdamond_pid_read(struct file *file,
 
 static int damon_dbgfs_open(struct inode *inode, struct file *file)
 {
+	damon_dbgfs_warn_deprecation();
+
 	file->private_data = inode->i_private;
 
 	return nonseekable_open(inode, file);
@@ -1039,15 +1046,24 @@ static ssize_t dbgfs_monitor_on_write(struct file *file,
 	return ret;
 }
 
+static int damon_dbgfs_static_file_open(struct inode *inode, struct file *file)
+{
+	damon_dbgfs_warn_deprecation();
+	return nonseekable_open(inode, file);
+}
+
 static const struct file_operations mk_contexts_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.write = dbgfs_mk_context_write,
 };
 
 static const struct file_operations rm_contexts_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.write = dbgfs_rm_context_write,
 };
 
 static const struct file_operations monitor_on_fops = {
+	.open = damon_dbgfs_static_file_open,
 	.read = dbgfs_monitor_on_read,
 	.write = dbgfs_monitor_on_write,
 };
-- 
2.25.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v2 2/3] virtiofs: export filesystem tags through sysfs
  @ 2024-02-08 19:32  5% ` Stefan Hajnoczi
  0 siblings, 0 replies; 200+ results
From: Stefan Hajnoczi @ 2024-02-08 19:32 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Alyssa Ross, gmaglione, virtio-fs, vgoyal, mzxreary, Greg KH,
	miklos, Stefan Hajnoczi

The virtiofs filesystem is mounted using a "tag" which is exported by
the virtiofs device:

  # mount -t virtiofs <tag> /mnt

The virtiofs driver knows about all the available tags but these are
currently not exported to user space.

People have asked for these tags to be exported to user space. Most
recently Lennart Poettering has asked for it as he wants to scan the
tags and mount virtiofs automatically in certain cases.

https://gitlab.com/virtio-fs/virtiofsd/-/issues/128

This patch exports tags at /sys/fs/virtiofs/<N>/tag where N is the id of
the virtiofs device. The filesystem tag can be obtained by reading this
"tag" file.

There is also a symlink at /sys/fs/virtiofs/<N>/device that points to
the virtiofs device that exports this tag.

This patch converts the existing struct virtio_fs into a full kobject.
It already had a refcount so it's an easy change. The virtio_fs objects
can then be exposed in a kset at /sys/fs/virtiofs/. Note that virtio_fs
objects may live slightly longer than we wish for them to be exposed to
userspace, so kobject_del() is called explicitly when the underlying
virtio_device is removed. The virtio_fs object is freed when all
references are dropped (e.g. active mounts) but disappears as soon as
the virtiofs device is gone.

Originally-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 fs/fuse/virtio_fs.c                         | 113 ++++++++++++++++----
 Documentation/ABI/testing/sysfs-fs-virtiofs |  11 ++
 2 files changed, 103 insertions(+), 21 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-fs-virtiofs

diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index de9a38efdf1e..28e96b7cde00 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -31,6 +31,9 @@
 static DEFINE_MUTEX(virtio_fs_mutex);
 static LIST_HEAD(virtio_fs_instances);
 
+/* The /sys/fs/virtio_fs/ kset */
+static struct kset *virtio_fs_kset;
+
 enum {
 	VQ_HIPRIO,
 	VQ_REQUEST
@@ -55,7 +58,7 @@ struct virtio_fs_vq {
 
 /* A virtio-fs device instance */
 struct virtio_fs {
-	struct kref refcount;
+	struct kobject kobj;
 	struct list_head list;    /* on virtio_fs_instances */
 	char *tag;
 	struct virtio_fs_vq *vqs;
@@ -161,18 +164,43 @@ static inline void dec_in_flight_req(struct virtio_fs_vq *fsvq)
 		complete(&fsvq->in_flight_zero);
 }
 
-static void release_virtio_fs_obj(struct kref *ref)
+static ssize_t virtio_fs_tag_attr_show(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
 {
-	struct virtio_fs *vfs = container_of(ref, struct virtio_fs, refcount);
+	struct virtio_fs *fs = container_of(kobj, struct virtio_fs, kobj);
+
+	return sysfs_emit(buf, fs->tag);
+}
+
+static struct kobj_attribute virtio_fs_tag_attr = {
+	.attr = { .name = "tag", .mode= 0644 },
+	.show = virtio_fs_tag_attr_show,
+};
+
+static struct attribute *virtio_fs_attrs[] = {
+	&virtio_fs_tag_attr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(virtio_fs);
+
+static void virtio_fs_ktype_release(struct kobject *kobj)
+{
+	struct virtio_fs *vfs = container_of(kobj, struct virtio_fs, kobj);
 
 	kfree(vfs->vqs);
 	kfree(vfs);
 }
 
+static const struct kobj_type virtio_fs_ktype = {
+	.release = virtio_fs_ktype_release,
+	.sysfs_ops = &kobj_sysfs_ops,
+	.default_groups = virtio_fs_groups,
+};
+
 /* Make sure virtiofs_mutex is held */
 static void virtio_fs_put(struct virtio_fs *fs)
 {
-	kref_put(&fs->refcount, release_virtio_fs_obj);
+	kobject_put(&fs->kobj);
 }
 
 static void virtio_fs_fiq_release(struct fuse_iqueue *fiq)
@@ -243,25 +271,44 @@ static void virtio_fs_start_all_queues(struct virtio_fs *fs)
 }
 
 /* Add a new instance to the list or return -EEXIST if tag name exists*/
-static int virtio_fs_add_instance(struct virtio_fs *fs)
+static int virtio_fs_add_instance(struct virtio_device *vdev,
+				  struct virtio_fs *fs)
 {
 	struct virtio_fs *fs2;
-	bool duplicate = false;
+	int ret;
 
 	mutex_lock(&virtio_fs_mutex);
 
 	list_for_each_entry(fs2, &virtio_fs_instances, list) {
-		if (strcmp(fs->tag, fs2->tag) == 0)
-			duplicate = true;
+		if (strcmp(fs->tag, fs2->tag) == 0) {
+			mutex_unlock(&virtio_fs_mutex);
+			return -EEXIST;
+		}
 	}
 
-	if (!duplicate)
-		list_add_tail(&fs->list, &virtio_fs_instances);
+	/* Use the virtio_device's index as a unique identifier, there is no
+	 * need to allocate our own identifiers because the virtio_fs instance
+	 * is only visible to userspace as long as the underlying virtio_device
+	 * exists.
+	 */
+	fs->kobj.kset = virtio_fs_kset;
+	ret = kobject_add(&fs->kobj, NULL, "%d", vdev->index);
+	if (ret < 0) {
+		mutex_unlock(&virtio_fs_mutex);
+		return ret;
+	}
+
+	ret = sysfs_create_link(&fs->kobj, &vdev->dev.kobj, "device");
+	if (ret < 0) {
+		kobject_del(&fs->kobj);
+		mutex_unlock(&virtio_fs_mutex);
+		return ret;
+	}
+
+	list_add_tail(&fs->list, &virtio_fs_instances);
 
 	mutex_unlock(&virtio_fs_mutex);
 
-	if (duplicate)
-		return -EEXIST;
 	return 0;
 }
 
@@ -274,7 +321,7 @@ static struct virtio_fs *virtio_fs_find_instance(const char *tag)
 
 	list_for_each_entry(fs, &virtio_fs_instances, list) {
 		if (strcmp(fs->tag, tag) == 0) {
-			kref_get(&fs->refcount);
+			kobject_get(&fs->kobj);
 			goto found;
 		}
 	}
@@ -875,7 +922,7 @@ static int virtio_fs_probe(struct virtio_device *vdev)
 	fs = kzalloc(sizeof(*fs), GFP_KERNEL);
 	if (!fs)
 		return -ENOMEM;
-	kref_init(&fs->refcount);
+	kobject_init(&fs->kobj, &virtio_fs_ktype);
 	vdev->priv = fs;
 
 	ret = virtio_fs_read_tag(vdev, fs);
@@ -897,7 +944,7 @@ static int virtio_fs_probe(struct virtio_device *vdev)
 	 */
 	virtio_device_ready(vdev);
 
-	ret = virtio_fs_add_instance(fs);
+	ret = virtio_fs_add_instance(vdev, fs);
 	if (ret < 0)
 		goto out_vqs;
 
@@ -906,11 +953,10 @@ static int virtio_fs_probe(struct virtio_device *vdev)
 out_vqs:
 	virtio_reset_device(vdev);
 	virtio_fs_cleanup_vqs(vdev);
-	kfree(fs->vqs);
 
 out:
 	vdev->priv = NULL;
-	kfree(fs);
+	kobject_put(&fs->kobj);
 	return ret;
 }
 
@@ -934,6 +980,8 @@ static void virtio_fs_remove(struct virtio_device *vdev)
 	mutex_lock(&virtio_fs_mutex);
 	/* This device is going away. No one should get new reference */
 	list_del_init(&fs->list);
+	sysfs_remove_link(&fs->kobj, "device");
+	kobject_del(&fs->kobj);
 	virtio_fs_stop_all_queues(fs);
 	virtio_fs_drain_all_queues_locked(fs);
 	virtio_reset_device(vdev);
@@ -1520,6 +1568,20 @@ static struct file_system_type virtio_fs_type = {
 	.kill_sb	= virtio_kill_sb,
 };
 
+static int __init virtio_fs_sysfs_init(void)
+{
+	virtio_fs_kset = kset_create_and_add("virtiofs", NULL, fs_kobj);
+	if (!virtio_fs_kset)
+		return -ENOMEM;
+	return 0;
+}
+
+static void __exit virtio_fs_sysfs_exit(void)
+{
+	kset_unregister(virtio_fs_kset);
+	virtio_fs_kset = NULL;
+}
+
 static int __init virtio_fs_init(void)
 {
 	int ret;
@@ -1528,19 +1590,28 @@ static int __init virtio_fs_init(void)
 	if (ret < 0)
 		return ret;
 
+	ret = virtio_fs_sysfs_init();
+	if (ret < 0)
+		goto unregister_virtio_driver;
+
 	ret = register_filesystem(&virtio_fs_type);
-	if (ret < 0) {
-		unregister_virtio_driver(&virtio_fs_driver);
-		return ret;
-	}
+	if (ret < 0)
+		goto sysfs_exit;
 
 	return 0;
+
+sysfs_exit:
+	virtio_fs_sysfs_exit();
+unregister_virtio_driver:
+	unregister_virtio_driver(&virtio_fs_driver);
+	return ret;
 }
 module_init(virtio_fs_init);
 
 static void __exit virtio_fs_exit(void)
 {
 	unregister_filesystem(&virtio_fs_type);
+	virtio_fs_sysfs_exit();
 	unregister_virtio_driver(&virtio_fs_driver);
 }
 module_exit(virtio_fs_exit);
diff --git a/Documentation/ABI/testing/sysfs-fs-virtiofs b/Documentation/ABI/testing/sysfs-fs-virtiofs
new file mode 100644
index 000000000000..4839dbce997e
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-fs-virtiofs
@@ -0,0 +1,11 @@
+What:		/sys/fs/virtiofs/<n>/tag
+Date:		Feb 2024
+Contact:	virtio-fs@lists.linux.dev
+Description:
+		[RO] The mount "tag" that can be used to mount this filesystem.
+
+What:		/sys/fs/virtiofs/<n>/device
+Date:		Feb 2024
+Contact:	virtio-fs@lists.linux.dev
+Description:
+		Symlink to the virtio device that exports this filesystem.
-- 
2.43.0


^ permalink raw reply related	[relevance 5%]

* [PATCH v4 2/3] virtiofs: export filesystem tags through sysfs
  @ 2024-02-13  0:11  5% ` Stefan Hajnoczi
  0 siblings, 0 replies; 200+ results
From: Stefan Hajnoczi @ 2024-02-13  0:11 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: miklos, Greg KH, Alyssa Ross, mzxreary, gmaglione, vgoyal,
	virtio-fs, Stefan Hajnoczi

The virtiofs filesystem is mounted using a "tag" which is exported by
the virtiofs device:

  # mount -t virtiofs <tag> /mnt

The virtiofs driver knows about all the available tags but these are
currently not exported to user space.

People have asked for these tags to be exported to user space. Most
recently Lennart Poettering has asked for it as he wants to scan the
tags and mount virtiofs automatically in certain cases.

https://gitlab.com/virtio-fs/virtiofsd/-/issues/128

This patch exports tags at /sys/fs/virtiofs/<N>/tag where N is the id of
the virtiofs device. The filesystem tag can be obtained by reading this
"tag" file.

There is also a symlink at /sys/fs/virtiofs/<N>/device that points to
the virtiofs device that exports this tag.

This patch converts the existing struct virtio_fs into a full kobject.
It already had a refcount so it's an easy change. The virtio_fs objects
can then be exposed in a kset at /sys/fs/virtiofs/. Note that virtio_fs
objects may live slightly longer than we wish for them to be exposed to
userspace, so kobject_del() is called explicitly when the underlying
virtio_device is removed. The virtio_fs object is freed when all
references are dropped (e.g. active mounts) but disappears as soon as
the virtiofs device is gone.

Originally-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 fs/fuse/virtio_fs.c                         | 112 ++++++++++++++++----
 Documentation/ABI/testing/sysfs-fs-virtiofs |  11 ++
 2 files changed, 101 insertions(+), 22 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-fs-virtiofs

diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index d84dacbdce2c..99b6113bbd13 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -31,6 +31,9 @@
 static DEFINE_MUTEX(virtio_fs_mutex);
 static LIST_HEAD(virtio_fs_instances);
 
+/* The /sys/fs/virtio_fs/ kset */
+static struct kset *virtio_fs_kset;
+
 enum {
 	VQ_HIPRIO,
 	VQ_REQUEST
@@ -55,7 +58,7 @@ struct virtio_fs_vq {
 
 /* A virtio-fs device instance */
 struct virtio_fs {
-	struct kref refcount;
+	struct kobject kobj;
 	struct list_head list;    /* on virtio_fs_instances */
 	char *tag;
 	struct virtio_fs_vq *vqs;
@@ -161,18 +164,40 @@ static inline void dec_in_flight_req(struct virtio_fs_vq *fsvq)
 		complete(&fsvq->in_flight_zero);
 }
 
-static void release_virtio_fs_obj(struct kref *ref)
+static ssize_t tag_show(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
 {
-	struct virtio_fs *vfs = container_of(ref, struct virtio_fs, refcount);
+	struct virtio_fs *fs = container_of(kobj, struct virtio_fs, kobj);
+
+	return sysfs_emit(buf, fs->tag);
+}
+
+static struct kobj_attribute virtio_fs_tag_attr = __ATTR_RO(tag);
+
+static struct attribute *virtio_fs_attrs[] = {
+	&virtio_fs_tag_attr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(virtio_fs);
+
+static void virtio_fs_ktype_release(struct kobject *kobj)
+{
+	struct virtio_fs *vfs = container_of(kobj, struct virtio_fs, kobj);
 
 	kfree(vfs->vqs);
 	kfree(vfs);
 }
 
+static const struct kobj_type virtio_fs_ktype = {
+	.release = virtio_fs_ktype_release,
+	.sysfs_ops = &kobj_sysfs_ops,
+	.default_groups = virtio_fs_groups,
+};
+
 /* Make sure virtiofs_mutex is held */
 static void virtio_fs_put(struct virtio_fs *fs)
 {
-	kref_put(&fs->refcount, release_virtio_fs_obj);
+	kobject_put(&fs->kobj);
 }
 
 static void virtio_fs_fiq_release(struct fuse_iqueue *fiq)
@@ -243,25 +268,44 @@ static void virtio_fs_start_all_queues(struct virtio_fs *fs)
 }
 
 /* Add a new instance to the list or return -EEXIST if tag name exists*/
-static int virtio_fs_add_instance(struct virtio_fs *fs)
+static int virtio_fs_add_instance(struct virtio_device *vdev,
+				  struct virtio_fs *fs)
 {
 	struct virtio_fs *fs2;
-	bool duplicate = false;
+	int ret;
 
 	mutex_lock(&virtio_fs_mutex);
 
 	list_for_each_entry(fs2, &virtio_fs_instances, list) {
-		if (strcmp(fs->tag, fs2->tag) == 0)
-			duplicate = true;
+		if (strcmp(fs->tag, fs2->tag) == 0) {
+			mutex_unlock(&virtio_fs_mutex);
+			return -EEXIST;
+		}
 	}
 
-	if (!duplicate)
-		list_add_tail(&fs->list, &virtio_fs_instances);
+	/* Use the virtio_device's index as a unique identifier, there is no
+	 * need to allocate our own identifiers because the virtio_fs instance
+	 * is only visible to userspace as long as the underlying virtio_device
+	 * exists.
+	 */
+	fs->kobj.kset = virtio_fs_kset;
+	ret = kobject_add(&fs->kobj, NULL, "%d", vdev->index);
+	if (ret < 0) {
+		mutex_unlock(&virtio_fs_mutex);
+		return ret;
+	}
+
+	ret = sysfs_create_link(&fs->kobj, &vdev->dev.kobj, "device");
+	if (ret < 0) {
+		kobject_del(&fs->kobj);
+		mutex_unlock(&virtio_fs_mutex);
+		return ret;
+	}
+
+	list_add_tail(&fs->list, &virtio_fs_instances);
 
 	mutex_unlock(&virtio_fs_mutex);
 
-	if (duplicate)
-		return -EEXIST;
 	return 0;
 }
 
@@ -274,7 +318,7 @@ static struct virtio_fs *virtio_fs_find_instance(const char *tag)
 
 	list_for_each_entry(fs, &virtio_fs_instances, list) {
 		if (strcmp(fs->tag, tag) == 0) {
-			kref_get(&fs->refcount);
+			kobject_get(&fs->kobj);
 			goto found;
 		}
 	}
@@ -875,7 +919,7 @@ static int virtio_fs_probe(struct virtio_device *vdev)
 	fs = kzalloc(sizeof(*fs), GFP_KERNEL);
 	if (!fs)
 		return -ENOMEM;
-	kref_init(&fs->refcount);
+	kobject_init(&fs->kobj, &virtio_fs_ktype);
 	vdev->priv = fs;
 
 	ret = virtio_fs_read_tag(vdev, fs);
@@ -897,7 +941,7 @@ static int virtio_fs_probe(struct virtio_device *vdev)
 	 */
 	virtio_device_ready(vdev);
 
-	ret = virtio_fs_add_instance(fs);
+	ret = virtio_fs_add_instance(vdev, fs);
 	if (ret < 0)
 		goto out_vqs;
 
@@ -906,11 +950,10 @@ static int virtio_fs_probe(struct virtio_device *vdev)
 out_vqs:
 	virtio_reset_device(vdev);
 	virtio_fs_cleanup_vqs(vdev);
-	kfree(fs->vqs);
 
 out:
 	vdev->priv = NULL;
-	kfree(fs);
+	kobject_put(&fs->kobj);
 	return ret;
 }
 
@@ -934,6 +977,8 @@ static void virtio_fs_remove(struct virtio_device *vdev)
 	mutex_lock(&virtio_fs_mutex);
 	/* This device is going away. No one should get new reference */
 	list_del_init(&fs->list);
+	sysfs_remove_link(&fs->kobj, "device");
+	kobject_del(&fs->kobj);
 	virtio_fs_stop_all_queues(fs);
 	virtio_fs_drain_all_queues_locked(fs);
 	virtio_reset_device(vdev);
@@ -1520,21 +1565,43 @@ static struct file_system_type virtio_fs_type = {
 	.kill_sb	= virtio_kill_sb,
 };
 
+static int __init virtio_fs_sysfs_init(void)
+{
+	virtio_fs_kset = kset_create_and_add("virtiofs", NULL, fs_kobj);
+	if (!virtio_fs_kset)
+		return -ENOMEM;
+	return 0;
+}
+
+static void __exit virtio_fs_sysfs_exit(void)
+{
+	kset_unregister(virtio_fs_kset);
+	virtio_fs_kset = NULL;
+}
+
 static int __init virtio_fs_init(void)
 {
 	int ret;
 
+	ret = virtio_fs_sysfs_init();
+	if (ret < 0)
+		return ret;
+
 	ret = register_virtio_driver(&virtio_fs_driver);
 	if (ret < 0)
-		return ret;
+		goto sysfs_exit;
 
 	ret = register_filesystem(&virtio_fs_type);
-	if (ret < 0) {
-		unregister_virtio_driver(&virtio_fs_driver);
-		return ret;
-	}
+	if (ret < 0)
+		goto unregister_virtio_driver;
 
 	return 0;
+
+unregister_virtio_driver:
+	unregister_virtio_driver(&virtio_fs_driver);
+sysfs_exit:
+	virtio_fs_sysfs_exit();
+	return ret;
 }
 module_init(virtio_fs_init);
 
@@ -1542,6 +1609,7 @@ static void __exit virtio_fs_exit(void)
 {
 	unregister_filesystem(&virtio_fs_type);
 	unregister_virtio_driver(&virtio_fs_driver);
+	virtio_fs_sysfs_exit();
 }
 module_exit(virtio_fs_exit);
 
diff --git a/Documentation/ABI/testing/sysfs-fs-virtiofs b/Documentation/ABI/testing/sysfs-fs-virtiofs
new file mode 100644
index 000000000000..4839dbce997e
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-fs-virtiofs
@@ -0,0 +1,11 @@
+What:		/sys/fs/virtiofs/<n>/tag
+Date:		Feb 2024
+Contact:	virtio-fs@lists.linux.dev
+Description:
+		[RO] The mount "tag" that can be used to mount this filesystem.
+
+What:		/sys/fs/virtiofs/<n>/device
+Date:		Feb 2024
+Contact:	virtio-fs@lists.linux.dev
+Description:
+		Symlink to the virtio device that exports this filesystem.
-- 
2.43.0


^ permalink raw reply related	[relevance 5%]

* [PATCH v3 2/3] virtiofs: export filesystem tags through sysfs
  @ 2024-02-09 12:18  5% ` Stefan Hajnoczi
  0 siblings, 0 replies; 200+ results
From: Stefan Hajnoczi @ 2024-02-09 12:18 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: miklos, gmaglione, Greg KH, virtio-fs, vgoyal, Alyssa Ross,
	mzxreary, Stefan Hajnoczi

The virtiofs filesystem is mounted using a "tag" which is exported by
the virtiofs device:

  # mount -t virtiofs <tag> /mnt

The virtiofs driver knows about all the available tags but these are
currently not exported to user space.

People have asked for these tags to be exported to user space. Most
recently Lennart Poettering has asked for it as he wants to scan the
tags and mount virtiofs automatically in certain cases.

https://gitlab.com/virtio-fs/virtiofsd/-/issues/128

This patch exports tags at /sys/fs/virtiofs/<N>/tag where N is the id of
the virtiofs device. The filesystem tag can be obtained by reading this
"tag" file.

There is also a symlink at /sys/fs/virtiofs/<N>/device that points to
the virtiofs device that exports this tag.

This patch converts the existing struct virtio_fs into a full kobject.
It already had a refcount so it's an easy change. The virtio_fs objects
can then be exposed in a kset at /sys/fs/virtiofs/. Note that virtio_fs
objects may live slightly longer than we wish for them to be exposed to
userspace, so kobject_del() is called explicitly when the underlying
virtio_device is removed. The virtio_fs object is freed when all
references are dropped (e.g. active mounts) but disappears as soon as
the virtiofs device is gone.

Originally-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 fs/fuse/virtio_fs.c                         | 110 ++++++++++++++++----
 Documentation/ABI/testing/sysfs-fs-virtiofs |  11 ++
 2 files changed, 100 insertions(+), 21 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-fs-virtiofs

diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index d84dacbdce2c..22d7c70ef78a 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -31,6 +31,9 @@
 static DEFINE_MUTEX(virtio_fs_mutex);
 static LIST_HEAD(virtio_fs_instances);
 
+/* The /sys/fs/virtio_fs/ kset */
+static struct kset *virtio_fs_kset;
+
 enum {
 	VQ_HIPRIO,
 	VQ_REQUEST
@@ -55,7 +58,7 @@ struct virtio_fs_vq {
 
 /* A virtio-fs device instance */
 struct virtio_fs {
-	struct kref refcount;
+	struct kobject kobj;
 	struct list_head list;    /* on virtio_fs_instances */
 	char *tag;
 	struct virtio_fs_vq *vqs;
@@ -161,18 +164,40 @@ static inline void dec_in_flight_req(struct virtio_fs_vq *fsvq)
 		complete(&fsvq->in_flight_zero);
 }
 
-static void release_virtio_fs_obj(struct kref *ref)
+static ssize_t tag_show(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
 {
-	struct virtio_fs *vfs = container_of(ref, struct virtio_fs, refcount);
+	struct virtio_fs *fs = container_of(kobj, struct virtio_fs, kobj);
+
+	return sysfs_emit(buf, fs->tag);
+}
+
+static struct kobj_attribute virtio_fs_tag_attr = __ATTR_RO(tag);
+
+static struct attribute *virtio_fs_attrs[] = {
+	&virtio_fs_tag_attr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(virtio_fs);
+
+static void virtio_fs_ktype_release(struct kobject *kobj)
+{
+	struct virtio_fs *vfs = container_of(kobj, struct virtio_fs, kobj);
 
 	kfree(vfs->vqs);
 	kfree(vfs);
 }
 
+static const struct kobj_type virtio_fs_ktype = {
+	.release = virtio_fs_ktype_release,
+	.sysfs_ops = &kobj_sysfs_ops,
+	.default_groups = virtio_fs_groups,
+};
+
 /* Make sure virtiofs_mutex is held */
 static void virtio_fs_put(struct virtio_fs *fs)
 {
-	kref_put(&fs->refcount, release_virtio_fs_obj);
+	kobject_put(&fs->kobj);
 }
 
 static void virtio_fs_fiq_release(struct fuse_iqueue *fiq)
@@ -243,25 +268,44 @@ static void virtio_fs_start_all_queues(struct virtio_fs *fs)
 }
 
 /* Add a new instance to the list or return -EEXIST if tag name exists*/
-static int virtio_fs_add_instance(struct virtio_fs *fs)
+static int virtio_fs_add_instance(struct virtio_device *vdev,
+				  struct virtio_fs *fs)
 {
 	struct virtio_fs *fs2;
-	bool duplicate = false;
+	int ret;
 
 	mutex_lock(&virtio_fs_mutex);
 
 	list_for_each_entry(fs2, &virtio_fs_instances, list) {
-		if (strcmp(fs->tag, fs2->tag) == 0)
-			duplicate = true;
+		if (strcmp(fs->tag, fs2->tag) == 0) {
+			mutex_unlock(&virtio_fs_mutex);
+			return -EEXIST;
+		}
 	}
 
-	if (!duplicate)
-		list_add_tail(&fs->list, &virtio_fs_instances);
+	/* Use the virtio_device's index as a unique identifier, there is no
+	 * need to allocate our own identifiers because the virtio_fs instance
+	 * is only visible to userspace as long as the underlying virtio_device
+	 * exists.
+	 */
+	fs->kobj.kset = virtio_fs_kset;
+	ret = kobject_add(&fs->kobj, NULL, "%d", vdev->index);
+	if (ret < 0) {
+		mutex_unlock(&virtio_fs_mutex);
+		return ret;
+	}
+
+	ret = sysfs_create_link(&fs->kobj, &vdev->dev.kobj, "device");
+	if (ret < 0) {
+		kobject_del(&fs->kobj);
+		mutex_unlock(&virtio_fs_mutex);
+		return ret;
+	}
+
+	list_add_tail(&fs->list, &virtio_fs_instances);
 
 	mutex_unlock(&virtio_fs_mutex);
 
-	if (duplicate)
-		return -EEXIST;
 	return 0;
 }
 
@@ -274,7 +318,7 @@ static struct virtio_fs *virtio_fs_find_instance(const char *tag)
 
 	list_for_each_entry(fs, &virtio_fs_instances, list) {
 		if (strcmp(fs->tag, tag) == 0) {
-			kref_get(&fs->refcount);
+			kobject_get(&fs->kobj);
 			goto found;
 		}
 	}
@@ -875,7 +919,7 @@ static int virtio_fs_probe(struct virtio_device *vdev)
 	fs = kzalloc(sizeof(*fs), GFP_KERNEL);
 	if (!fs)
 		return -ENOMEM;
-	kref_init(&fs->refcount);
+	kobject_init(&fs->kobj, &virtio_fs_ktype);
 	vdev->priv = fs;
 
 	ret = virtio_fs_read_tag(vdev, fs);
@@ -897,7 +941,7 @@ static int virtio_fs_probe(struct virtio_device *vdev)
 	 */
 	virtio_device_ready(vdev);
 
-	ret = virtio_fs_add_instance(fs);
+	ret = virtio_fs_add_instance(vdev, fs);
 	if (ret < 0)
 		goto out_vqs;
 
@@ -906,11 +950,10 @@ static int virtio_fs_probe(struct virtio_device *vdev)
 out_vqs:
 	virtio_reset_device(vdev);
 	virtio_fs_cleanup_vqs(vdev);
-	kfree(fs->vqs);
 
 out:
 	vdev->priv = NULL;
-	kfree(fs);
+	kobject_put(&fs->kobj);
 	return ret;
 }
 
@@ -934,6 +977,8 @@ static void virtio_fs_remove(struct virtio_device *vdev)
 	mutex_lock(&virtio_fs_mutex);
 	/* This device is going away. No one should get new reference */
 	list_del_init(&fs->list);
+	sysfs_remove_link(&fs->kobj, "device");
+	kobject_del(&fs->kobj);
 	virtio_fs_stop_all_queues(fs);
 	virtio_fs_drain_all_queues_locked(fs);
 	virtio_reset_device(vdev);
@@ -1520,6 +1565,20 @@ static struct file_system_type virtio_fs_type = {
 	.kill_sb	= virtio_kill_sb,
 };
 
+static int __init virtio_fs_sysfs_init(void)
+{
+	virtio_fs_kset = kset_create_and_add("virtiofs", NULL, fs_kobj);
+	if (!virtio_fs_kset)
+		return -ENOMEM;
+	return 0;
+}
+
+static void __exit virtio_fs_sysfs_exit(void)
+{
+	kset_unregister(virtio_fs_kset);
+	virtio_fs_kset = NULL;
+}
+
 static int __init virtio_fs_init(void)
 {
 	int ret;
@@ -1528,19 +1587,28 @@ static int __init virtio_fs_init(void)
 	if (ret < 0)
 		return ret;
 
+	ret = virtio_fs_sysfs_init();
+	if (ret < 0)
+		goto unregister_virtio_driver;
+
 	ret = register_filesystem(&virtio_fs_type);
-	if (ret < 0) {
-		unregister_virtio_driver(&virtio_fs_driver);
-		return ret;
-	}
+	if (ret < 0)
+		goto sysfs_exit;
 
 	return 0;
+
+sysfs_exit:
+	virtio_fs_sysfs_exit();
+unregister_virtio_driver:
+	unregister_virtio_driver(&virtio_fs_driver);
+	return ret;
 }
 module_init(virtio_fs_init);
 
 static void __exit virtio_fs_exit(void)
 {
 	unregister_filesystem(&virtio_fs_type);
+	virtio_fs_sysfs_exit();
 	unregister_virtio_driver(&virtio_fs_driver);
 }
 module_exit(virtio_fs_exit);
diff --git a/Documentation/ABI/testing/sysfs-fs-virtiofs b/Documentation/ABI/testing/sysfs-fs-virtiofs
new file mode 100644
index 000000000000..4839dbce997e
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-fs-virtiofs
@@ -0,0 +1,11 @@
+What:		/sys/fs/virtiofs/<n>/tag
+Date:		Feb 2024
+Contact:	virtio-fs@lists.linux.dev
+Description:
+		[RO] The mount "tag" that can be used to mount this filesystem.
+
+What:		/sys/fs/virtiofs/<n>/device
+Date:		Feb 2024
+Contact:	virtio-fs@lists.linux.dev
+Description:
+		Symlink to the virtio device that exports this filesystem.
-- 
2.43.0


^ permalink raw reply related	[relevance 5%]

* 50% OFF din pret. nvdimm@lists.linux.dev
@ 2022-12-07 14:47  5% Publicitate digitala in mall-uri
  0 siblings, 0 replies; 200+ results
From: Publicitate digitala in mall-uri @ 2022-12-07 14:47 UTC (permalink / raw)
  To: nvdimm


[-- Attachment #1.1: Type: text/plain, Size: 4773 bytes --]





0771 303 303
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781832&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=tel%3A0771303303&_ntm_sentIdx=1ed763e0-012c-6caa-99cb-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397693&_ntm_usr=15532&_ntm_sig=96eda34ccb2535d02ed647a22c7768cb520a08a8ac0025af7aa42c404f7c2788)
office@ekogroup.ro
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781832&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=mailto%3Aoffice%40ekogroup.ro&_ntm_sentIdx=1ed763e0-012c-6caa-99cb-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397694&_ntm_usr=15532&_ntm_sig=5c368e9984511d1e8855193a587fae01abe8c0b8c71d704f8f729d6504005ed8)




Oferta digitala
DISCOUNT 50% din pretul chiriei TIMP DE 3 LUNI daca se semneaza si se achita 
contracte înaintea inceperii campaniilor!
  Primul totem la VERANDA mall dintr o serie de 5000 buc la nivel 
national(toate centrele comerciale din ROMANIA) în urmatorii 2 ani.   
Totemurile apartin companieiekogroup.ro 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781832&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=http%3A%2F%2Fekogroup.ro%2F&_ntm_sentIdx=1ed763e0-012c-6caa-99cb-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397695&_ntm_usr=15532&_ntm_sig=bca982cd4076f4dbd5372dcc4a60df81a3e3078a5079397be4742564869c243b)
(nu suntem revanzatori de servicii)   Putem facilita vanzarea media kit-urilor 
indoor si outdoor în toate centrele comerciale la preturi avantajoase.   
Preturile sunt negociabile în functie de perioada.   Urmatoarele proiecte pana 
la decembrie 2022- martie 2023:   Mall Veranda: - 7 totem toate etajele - 4 tv 
uri 86 inch food court - exclusivitate vanzare media kit indoor-outdoor  Data 
incepere campanii: 20 decembrie 2022 https://youtube.com/shorts/N0_m1WJUrYE 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781832&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=https%3A%2F%2Fyoutube.com%2Fshorts%2FN0_m1WJUrYE&_ntm_sentIdx=1ed763e0-012c-6caa-99cb-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397696&_ntm_usr=15532&_ntm_sig=538609566feeddd537f113dac25da49f7904b5f08cfa717da5fa25b6d62ca3e4)
  Cineplexx Baneasa: - videowall intrare cineplexx(vis a vis de Carturesti) 
https://drive.google.com/file/d/18tbAZ5KpOojmfyIK440n7wsSxF6k4W4m/view 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781832&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=https%3A%2F%2Fdrive.google.com%2Ffile%2Fd%2F18tbAZ5KpOojmfyIK440n7wsSxF6k4W4m%2Fview&_ntm_sentIdx=1ed763e0-012c-6caa-99cb-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397697&_ntm_usr=15532&_ntm_sig=e7862bb01eae558e9184ca96a77bd3212ef51eb49ca13f69a6bca3570eef6728)
- 2 totem 2300mm x 1230mm, 86 inch FOAYER Cineplexx Baneasa, PARTER - 1 totem 
subsol, vis a vis de sala VIP Data începere campanii: 1 martie 2023   Cineplexx 
TITAN: - 1 totem 98 inch intrare Cinplexx partea stânga - 2 totem 86 inch 
FOAYER langa stalpii de rezistenta - 1 totem 86 inch langa casele de 
bilete/popcorn - 2 totem 98 inch în proximitatea Foayerului salilor de cinema 
Data începere campanii: 15 ianuarie 2023   Reteaua KAUFLAND: - 1 totem 86 inch 
fata simpla la fiecare intrare/iesire KAUFLAND Bucuresti (Total avem 18 
locaÈ›ii, câte un totem pe fiecare locaÈ›ie) Data începere campanii: 1 martie 
2023 
 





Solicita oferta
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781832&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=mailto%3Aoffice%40ekogroup.ro&_ntm_sentIdx=1ed763e0-012c-6caa-99cb-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397694&_ntm_usr=15532&_ntm_sig=5c368e9984511d1e8855193a587fae01abe8c0b8c71d704f8f729d6504005ed8)



 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781832&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=https%3A%2F%2Fwww.youtube.com%2Fshorts%2FN0_m1WJUrYE&_ntm_sentIdx=1ed763e0-012c-6caa-99cb-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397698&_ntm_usr=15532&_ntm_sig=98d76ff3d4a73321c5edf45db8bde1dedc7272d4167d6a41d867de86153b2501)




Solicita oferta
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281781832&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=mailto%3Aoffice%40ekogroup.ro&_ntm_sentIdx=1ed763e0-012c-6caa-99cb-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397694&_ntm_usr=15532&_ntm_sig=5c368e9984511d1e8855193a587fae01abe8c0b8c71d704f8f729d6504005ed8)




În conformitate cu prevederile Regulamentului (UE) 2016/679 din 27 aprilie 
2016 (GDPR), vă informăm că datele dumneavoastră cu caracter personal sunt 
prelucrate doar de către societatea noastră și au ca unic scop transmiterea de 
informații despre produsele și serviciile noastre. Vă puteți exercita 
drepturile de acces, de anulare.

Dezabonare  
(https://tracking3.360nrs.net/unsubscribe/mailing/15532/281781832/565323/ae8859f69a/null/)



[-- Attachment #1.2: Type: text/html, Size: 30214 bytes --]

^ permalink raw reply	[relevance 5%]

* [merged] maintainers-add-self-as-clang-reviewer.patch removed from -mm tree
@ 2022-04-10  4:39  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2022-04-10  4:39 UTC (permalink / raw)
  To: mm-commits, ndesaulniers, nathan, trix, akpm


The patch titled
     Subject: MAINTAINERS: add Tom as clang reviewer
has been removed from the -mm tree.  Its filename was
     maintainers-add-self-as-clang-reviewer.patch

This patch was dropped because it was merged into mainline or a subsystem tree

------------------------------------------------------
From: Tom Rix <trix@redhat.com>
Subject: MAINTAINERS: add Tom as clang reviewer

I have been helping with build breaks and other clang things and would
like to help with the reviews.

Link: https://lkml.kernel.org/r/20220407175715.3378998-1-trix@redhat.com
Signed-off-by: Tom Rix <trix@redhat.com>
Acked-by: Nathan Chancellor <nathan@kernel.org>
Acked-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 MAINTAINERS |    1 +
 1 file changed, 1 insertion(+)

--- a/MAINTAINERS~maintainers-add-self-as-clang-reviewer
+++ a/MAINTAINERS
@@ -4791,6 +4791,7 @@ F:	.clang-format
 CLANG/LLVM BUILD SUPPORT
 M:	Nathan Chancellor <nathan@kernel.org>
 M:	Nick Desaulniers <ndesaulniers@google.com>
+R:	Tom Rix <trix@redhat.com>
 L:	llvm@lists.linux.dev
 S:	Supported
 W:	https://clangbuiltlinux.github.io/
_

Patches currently in -mm which might be from trix@redhat.com are

lib-remove-back_str-initialization.patch


^ permalink raw reply	[relevance 5%]

* [PATCH] drivers: watchdog: Add ChromeOS EC watchdog
@ 2024-01-17 10:24  5% Lukasz Majczak
  0 siblings, 0 replies; 200+ results
From: Lukasz Majczak @ 2024-01-17 10:24 UTC (permalink / raw)
  To: Gwendal Grignou, Lee Jones, Benson Leung, Wim Van Sebroeck,
	Tzung-Bi Shih, Radoslaw Biernacki
  Cc: linux-kernel, chrome-platform, linux-watchdog, Lukasz Majczak

This adds EC-based watchdog support for ChromeOS
based devices equipped with embedded controller (EC).

Signed-off-by: Lukasz Majczak <lma@chromium.org>
---
 MAINTAINERS                                   |   6 +
 drivers/mfd/cros_ec_dev.c                     |   9 +
 drivers/watchdog/Kconfig                      |  15 +
 drivers/watchdog/Makefile                     |   3 +
 drivers/watchdog/cros_ec_wdt.c                | 303 ++++++++++++++++++
 .../linux/platform_data/cros_ec_commands.h    |  78 ++---
 6 files changed, 370 insertions(+), 44 deletions(-)
 create mode 100644 drivers/watchdog/cros_ec_wdt.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 391bbb855cbe..55cd626a525f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4952,6 +4952,12 @@ R:	Sami Kyöstilä <skyostil@chromium.org>
 S:	Maintained
 F:	drivers/platform/chrome/cros_hps_i2c.c
 
+CHROMEOS EC WATCHDOG
+M:	Lukasz Majczak <lma@chromium.org>
+L:	chrome-platform@lists.linux.dev
+S:	Maintained
+F:	drivers/watchdog/cros_ec_wdt.c
+
 CHRONTEL CH7322 CEC DRIVER
 M:	Joe Tessler <jrt@google.com>
 L:	linux-media@vger.kernel.org
diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index 79d393b602bf..60fe831cf30a 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -91,6 +91,10 @@ static const struct mfd_cell cros_usbpd_notify_cells[] = {
 	{ .name = "cros-usbpd-notify", },
 };
 
+static const struct mfd_cell cros_ec_wdt_cells[] = {
+	{ .name = "cros-ec-wdt-drv", }
+};
+
 static const struct cros_feature_to_cells cros_subdevices[] = {
 	{
 		.id		= EC_FEATURE_CEC,
@@ -107,6 +111,11 @@ static const struct cros_feature_to_cells cros_subdevices[] = {
 		.mfd_cells	= cros_usbpd_charger_cells,
 		.num_cells	= ARRAY_SIZE(cros_usbpd_charger_cells),
 	},
+	{
+		.id		= EC_FEATURE_HANG_DETECT,
+		.mfd_cells	= cros_ec_wdt_cells,
+		.num_cells	= ARRAY_SIZE(cros_ec_wdt_cells),
+	},
 };
 
 static const struct mfd_cell cros_ec_platform_cells[] = {
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 7d22051b15a2..1da4be661be8 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -2251,4 +2251,19 @@ config KEEMBAY_WATCHDOG
 	  To compile this driver as a module, choose M here: the
 	  module will be called keembay_wdt.
 
+#
+# ChromeOS EC-based Watchdog
+#
+
+config CROS_EC_WATCHDOG
+	tristate "ChromeOS EC-based watchdog driver"
+	select WATCHDOG_CORE
+	depends on CROS_EC
+	help
+	  This is the watchdog driver for ChromeOS devices equipped with EC.
+	  The EC watchdog - when enabled - expects to be kicked within a given
+	  time (default set to 30 seconds) otherwise it will simple reboot
+	  the AP. Priori to that it can also send an event (configurable timeout)
+	  about upcoming reboot.
+
 endif # WATCHDOG
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 7cbc34514ec1..8295c209ddb0 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -234,3 +234,6 @@ obj-$(CONFIG_MENZ069_WATCHDOG) += menz69_wdt.o
 obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o
 obj-$(CONFIG_STPMIC1_WATCHDOG) += stpmic1_wdt.o
 obj-$(CONFIG_SL28CPLD_WATCHDOG) += sl28cpld_wdt.o
+
+# Cros EC watchdog
+obj-$(CONFIG_CROS_EC_WATCHDOG) += cros_ec_wdt.o
diff --git a/drivers/watchdog/cros_ec_wdt.c b/drivers/watchdog/cros_ec_wdt.c
new file mode 100644
index 000000000000..b461c0613269
--- /dev/null
+++ b/drivers/watchdog/cros_ec_wdt.c
@@ -0,0 +1,303 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/of_device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_data/cros_ec_commands.h>
+#include <linux/platform_data/cros_ec_proto.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+#include <linux/uaccess.h>
+
+#define CROS_EC_WATCHDOG_DEFAULT_TIME 30 /* seconds */
+
+#define DEV_NAME "cros-ec-wdt-dev"
+#define DRV_NAME "cros-ec-wdt-drv"
+
+static int cros_ec_wdt_ping(struct watchdog_device *wdd);
+static int cros_ec_wdt_start(struct watchdog_device *wdd);
+static int cros_ec_wdt_stop(struct watchdog_device *wdd);
+static int cros_ec_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t);
+
+struct cros_ec_wdt_data {
+	bool start_on_resume;
+	bool keepalive_on;
+	struct cros_ec_device *cros_ec;
+	struct watchdog_device *wdd;
+};
+static struct cros_ec_wdt_data wd_data;
+
+static const struct watchdog_info cros_ec_wdt_ident = {
+	.options          = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
+	.firmware_version = 0,
+	.identity         = DRV_NAME,
+};
+
+static const struct watchdog_ops cros_ec_wdt_ops = {
+	.owner		 = THIS_MODULE,
+	.ping		 = cros_ec_wdt_ping,
+	.start		 = cros_ec_wdt_start,
+	.stop		 = cros_ec_wdt_stop,
+	.set_timeout = cros_ec_wdt_set_timeout,
+};
+
+static struct watchdog_device cros_ec_wdd = {
+	.info = &cros_ec_wdt_ident,
+	.ops = &cros_ec_wdt_ops,
+	.timeout = CROS_EC_WATCHDOG_DEFAULT_TIME,
+	.bootstatus = EC_HANG_DETECT_AP_BOOT_NORMAL
+};
+
+static int cros_ec_wdt_send_hang_detect(struct cros_ec_wdt_data *wd_data,
+					uint16_t command,
+					uint16_t reboot_timeout_sec,
+					uint32_t *status)
+{
+	int ret;
+
+	struct {
+		struct cros_ec_command msg;
+		union {
+			struct ec_params_hang_detect req;
+			struct ec_response_hang_detect resp;
+		};
+	} __packed buf = {
+		.msg = {
+			.version = 0,
+			.command = EC_CMD_HANG_DETECT,
+			.insize  = (command == EC_HANG_DETECT_CMD_GET_STATUS) ?
+				   sizeof(struct ec_response_hang_detect) :
+				   0,
+			.outsize = sizeof(struct ec_params_hang_detect),
+		},
+		.req = {
+			.command = command,
+			.reboot_timeout_sec = reboot_timeout_sec,
+		}
+	};
+
+	ret = cros_ec_cmd_xfer_status(wd_data->cros_ec, &buf.msg);
+	if (ret < 0) {
+		dev_warn(wd_data->wdd->parent,
+				 "cros_ec_cmd_xfer_status failed(%d) command (%04x) reboot_timeout_sec(%ds)",
+				 ret, command, reboot_timeout_sec);
+		return ret;
+	}
+
+	if (status && (command == EC_HANG_DETECT_CMD_GET_STATUS)) {
+		*status = buf.resp.status;
+		dev_info(wd_data->wdd->parent, "EC Watchdog boot status (%d)",
+				 buf.resp.status);
+	}
+
+	return 0;
+}
+
+static int cros_ec_wdt_ping(struct watchdog_device *wdd)
+{
+	struct cros_ec_wdt_data *wd_data = watchdog_get_drvdata(wdd);
+	int ret;
+
+	ret = cros_ec_wdt_send_hang_detect(wd_data, EC_HANG_DETECT_CMD_RELOAD,
+					   0, NULL);
+	if (ret < 0)
+		dev_err(wdd->parent, "%s failed (%d)", __func__, ret);
+	else
+		wd_data->keepalive_on = true;
+
+	return ret;
+}
+
+static int cros_ec_wdt_start(struct watchdog_device *wdd)
+{
+	struct cros_ec_wdt_data *wd_data = watchdog_get_drvdata(wdd);
+	int ret = 0;
+
+	/* Prepare watchdog on EC side */
+	ret = cros_ec_wdt_send_hang_detect(wd_data,
+					EC_HANG_DETECT_CMD_SET_TIMEOUT,
+					wdd->timeout,
+					NULL);
+	if (ret < 0)
+		dev_err(wdd->parent, "%s failed (%d)", __func__, ret);
+
+	return ret;
+}
+
+static int cros_ec_wdt_stop(struct watchdog_device *wdd)
+{
+	struct cros_ec_wdt_data *wd_data = watchdog_get_drvdata(wdd);
+	int ret = 0;
+
+	if (wd_data->keepalive_on) {
+		wd_data->keepalive_on = false;
+		ret = cros_ec_wdt_send_hang_detect(wd_data, EC_HANG_DETECT_CMD_CANCEL,
+						0, NULL);
+		if (ret < 0)
+			dev_err(wdd->parent, "%s failed (%d)", __func__, ret);
+	}
+
+	return ret;
+}
+
+static int cros_ec_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
+{
+	struct cros_ec_wdt_data *wd_data = watchdog_get_drvdata(wdd);
+	int ret;
+
+	if (t < EC_HANG_DETECT_MIN_TIMEOUT) {
+		dev_err(wdd->parent,
+				"%s failed, requested timeout is lower than min(%d < %d)",
+				__func__, t, EC_HANG_DETECT_MIN_TIMEOUT);
+		return -EINVAL;
+	}
+
+	ret = cros_ec_wdt_send_hang_detect(wd_data,
+					   EC_HANG_DETECT_CMD_SET_TIMEOUT,
+					   t, NULL);
+	if (ret < 0)
+		dev_err(wdd->parent, "%s failed (%d)", __func__, ret);
+	else
+		wdd->timeout = t;
+
+	return ret;
+}
+
+static int cros_ec_wdt_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	/* We need to get a reference to cros_ec_devices
+	 * (provides communication layer) which is a parent of
+	 * the cros-ec-dev (our parent)
+	 */
+	struct cros_ec_device *cros_ec = dev_get_drvdata(dev->parent->parent);
+	int ret = 0;
+	uint32_t bootstatus;
+
+	if (!cros_ec) {
+		ret = -ENODEV;
+		dev_err_probe(dev, ret, "There is no coresponding EC device!");
+		return ret;
+	}
+
+	cros_ec_wdd.parent = &pdev->dev;
+	wd_data.cros_ec = cros_ec;
+	wd_data.wdd = &cros_ec_wdd;
+	wd_data.start_on_resume = false;
+	wd_data.keepalive_on = false;
+	wd_data.wdd->timeout = CROS_EC_WATCHDOG_DEFAULT_TIME;
+
+	watchdog_stop_on_reboot(&cros_ec_wdd);
+	watchdog_stop_on_unregister(&cros_ec_wdd);
+	watchdog_set_drvdata(&cros_ec_wdd, &wd_data);
+	platform_set_drvdata(pdev, &wd_data);
+
+	/* Get current AP boot status */
+	ret = cros_ec_wdt_send_hang_detect(&wd_data, EC_HANG_DETECT_CMD_GET_STATUS, 0,
+					   &bootstatus);
+	if (ret < 0) {
+		dev_err_probe(dev, ret, "Couldn't get AP boot status from EC");
+		return ret;
+	}
+
+	/*
+	 * If bootstatus is not EC_HANG_DETECT_AP_BOOT_NORMAL
+	 * it mens EC has rebooted the AP due to watchdog timeout.
+	 * Lets translate it to watchdog core status code.
+	 */
+	if (bootstatus != EC_HANG_DETECT_AP_BOOT_NORMAL)
+		wd_data.wdd->bootstatus = WDIOF_CARDRESET;
+
+	ret = watchdog_register_device(&cros_ec_wdd);
+	if (ret < 0)
+		dev_err_probe(dev, ret, "Couldn't get AP boot status from EC");
+
+	return ret;
+}
+
+static int cros_ec_wdt_remove(struct platform_device *pdev)
+{
+	struct cros_ec_wdt_data *wd_data = platform_get_drvdata(pdev);
+
+	watchdog_unregister_device(wd_data->wdd);
+
+	return 0;
+}
+
+static void cros_ec_wdt_shutdown(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cros_ec_wdt_data *wd_data = platform_get_drvdata(pdev);
+	int ret;
+
+	/*
+	 * Clean only bootstatus flag.
+	 * EC wdt is are already stopped by watchdog framework.
+	 */
+	ret = cros_ec_wdt_send_hang_detect(wd_data,
+					   EC_HANG_DETECT_CMD_CLEAR_STATUS, 0, NULL);
+	if (ret < 0)
+		dev_err(dev, "%s failed (%d)", __func__, ret);
+
+	watchdog_unregister_device(wd_data->wdd);
+}
+
+static int __maybe_unused cros_ec_wdt_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct device *dev = &pdev->dev;
+	struct cros_ec_wdt_data *wd_data = platform_get_drvdata(pdev);
+	int ret;
+
+	if (watchdog_active(wd_data->wdd)) {
+		ret = cros_ec_wdt_send_hang_detect(wd_data,
+						   EC_HANG_DETECT_CMD_CANCEL, 0, NULL);
+		if (ret < 0)
+			dev_err(dev, "%s failed (%d)", __func__, ret);
+		wd_data->start_on_resume = true;
+	}
+
+	return 0;
+}
+
+static int __maybe_unused cros_ec_wdt_resume(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cros_ec_wdt_data *wd_data = platform_get_drvdata(pdev);
+	int ret;
+
+	/* start_on_resume is only set if watchdog was active
+	 * when device was going to sleep
+	 */
+	if (wd_data->start_on_resume) {
+		/* On resume we just need to setup a EC watchdog the same way as
+		 * in cros_ec_wdt_start(). When userspace resumes from suspend
+		 * the watchdog app should just start petting the watchdog again.
+		 */
+		ret = cros_ec_wdt_start(wd_data->wdd);
+		if (ret < 0)
+			dev_err(dev, "%s failed (%d)", __func__, ret);
+
+		wd_data->start_on_resume = false;
+	}
+
+	return 0;
+}
+
+static struct platform_driver cros_ec_wdt_driver = {
+	.probe		= cros_ec_wdt_probe,
+	.remove		= cros_ec_wdt_remove,
+	.shutdown	= cros_ec_wdt_shutdown,
+	.suspend	= pm_ptr(cros_ec_wdt_suspend),
+	.resume		= pm_ptr(cros_ec_wdt_resume),
+	.driver		= {
+		.name	= DRV_NAME,
+	},
+};
+
+module_platform_driver(cros_ec_wdt_driver);
+
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DESCRIPTION("Cros EC Watchdog Device Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h
index 7dae17b62a4d..35a7a2d32819 100644
--- a/include/linux/platform_data/cros_ec_commands.h
+++ b/include/linux/platform_data/cros_ec_commands.h
@@ -3961,60 +3961,50 @@ struct ec_response_i2c_passthru {
 } __ec_align1;
 
 /*****************************************************************************/
-/* Power button hang detect */
-
+/* AP hang detect */
 #define EC_CMD_HANG_DETECT 0x009F
 
-/* Reasons to start hang detection timer */
-/* Power button pressed */
-#define EC_HANG_START_ON_POWER_PRESS  BIT(0)
-
-/* Lid closed */
-#define EC_HANG_START_ON_LID_CLOSE    BIT(1)
-
- /* Lid opened */
-#define EC_HANG_START_ON_LID_OPEN     BIT(2)
-
-/* Start of AP S3->S0 transition (booting or resuming from suspend) */
-#define EC_HANG_START_ON_RESUME       BIT(3)
-
-/* Reasons to cancel hang detection */
+#define EC_HANG_DETECT_MIN_TIMEOUT 5
 
-/* Power button released */
-#define EC_HANG_STOP_ON_POWER_RELEASE BIT(8)
+/* EC hang detect commands */
+enum ec_hang_detect_cmds {
+	/* Reload AP hang detect timer. */
+	EC_HANG_DETECT_CMD_RELOAD = 0x0,
 
-/* Any host command from AP received */
-#define EC_HANG_STOP_ON_HOST_COMMAND  BIT(9)
+	/* Stop AP hang detect timer. */
+	EC_HANG_DETECT_CMD_CANCEL = 0x1,
 
-/* Stop on end of AP S0->S3 transition (suspending or shutting down) */
-#define EC_HANG_STOP_ON_SUSPEND       BIT(10)
+	/* Configure watchdog with given reboot timeout and
+	 * cancel currently running AP hand detect timer.
+	 */
+	EC_HANG_DETECT_CMD_SET_TIMEOUT = 0x2,
 
-/*
- * If this flag is set, all the other fields are ignored, and the hang detect
- * timer is started.  This provides the AP a way to start the hang timer
- * without reconfiguring any of the other hang detect settings.  Note that
- * you must previously have configured the timeouts.
- */
-#define EC_HANG_START_NOW             BIT(30)
+	/* Get last hang status - whether the AP boot was clear or not */
+	EC_HANG_DETECT_CMD_GET_STATUS = 0x3,
 
-/*
- * If this flag is set, all the other fields are ignored (including
- * EC_HANG_START_NOW).  This provides the AP a way to stop the hang timer
- * without reconfiguring any of the other hang detect settings.
- */
-#define EC_HANG_STOP_NOW              BIT(31)
+	/* Clear last hang status. Called when AP is rebooting/shutting down
+	 * gracefully.
+	 */
+	EC_HANG_DETECT_CMD_CLEAR_STATUS = 0x4
+};
 
 struct ec_params_hang_detect {
-	/* Flags; see EC_HANG_* */
-	uint32_t flags;
-
-	/* Timeout in msec before generating host event, if enabled */
-	uint16_t host_event_timeout_msec;
-
-	/* Timeout in msec before generating warm reboot, if enabled */
-	uint16_t warm_reboot_timeout_msec;
-} __ec_align4;
+	uint16_t command; /* enum ec_hang_detect_cmds */
+	/* Timeout in seconds before generating reboot */
+	uint16_t reboot_timeout_sec;
+} __ec_align2;
 
+/* Status codes that describe whether AP has boot normally or the hang has been
+ * detected and EC has reset AP
+ */
+enum ec_hang_detect_status {
+	EC_HANG_DETECT_AP_BOOT_NORMAL = 0x0,
+	EC_HANG_DETECT_AP_BOOT_EC_WDT = 0x1,
+	EC_HANG_DETECT_AP_BOOT_COUNT,
+};
+struct ec_response_hang_detect {
+	uint8_t status; /* enum ec_hang_detect_status */
+} __ec_align1;
 /*****************************************************************************/
 /* Commands for battery charging */
 
-- 
2.43.0.381.gb435a96ce8-goog


^ permalink raw reply related	[relevance 5%]

* [PATCH] README: fix typo
@ 2021-06-08 15:39  5% Alyssa Ross
  0 siblings, 0 replies; 200+ results
From: Alyssa Ross @ 2021-06-08 15:39 UTC (permalink / raw)
  To: connman; +Cc: Daniel Wagner

Signed-off-by: Alyssa Ross <hi@alyssa.is>
---
 README | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README b/README
index e36d796c..b8154e67 100644
--- a/README
+++ b/README
@@ -451,5 +451,5 @@ send a (empty) message from your email account to
 
 	connman+subscribe@lists.linux.dev
 
-Maling list archive:
+Mailing list archive:
 	https://lore.kernel.org/connman
-- 
2.31.0


^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: update cros_ec_codec maintainers
@ 2022-02-08  3:12  5% ` Tzung-Bi Shih
  0 siblings, 0 replies; 200+ results
From: Tzung-Bi Shih @ 2022-02-08  3:12 UTC (permalink / raw)
  To: broonie, cychiang, bleung; +Cc: alsa-devel, tzungbi, chrome-platform

Updates cros_ec_codec maintainers.

Signed-off-by: Tzung-Bi Shih <tzungbi@google.com>
---
 .../devicetree/bindings/sound/google,cros-ec-codec.yaml          | 1 +
 MAINTAINERS                                                      | 1 +
 2 files changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
index 77adbebed824..c3e9f3485449 100644
--- a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
+++ b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
@@ -8,6 +8,7 @@ title: Audio codec controlled by ChromeOS EC
 
 maintainers:
   - Cheng-Yi Chiang <cychiang@chromium.org>
+  - Tzung-Bi Shih <tzungbi@google.com>
 
 description: |
   Google's ChromeOS EC codec is a digital mic codec provided by the
diff --git a/MAINTAINERS b/MAINTAINERS
index 568152aa9973..a1f4fd15e770 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4573,6 +4573,7 @@ F:	drivers/platform/chrome/
 
 CHROMEOS EC CODEC DRIVER
 M:	Cheng-Yi Chiang <cychiang@chromium.org>
+M:	Tzung-Bi Shih <tzungbi@google.com>
 R:	Guenter Roeck <groeck@chromium.org>
 L:	chrome-platform@lists.linux.dev
 S:	Maintained
-- 
2.35.0.263.gb82422642f-goog


^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: update cros_ec_codec maintainers
@ 2022-02-08  3:12  5% ` Tzung-Bi Shih
  0 siblings, 0 replies; 200+ results
From: Tzung-Bi Shih @ 2022-02-08  3:12 UTC (permalink / raw)
  To: broonie, cychiang, bleung; +Cc: tzungbi, alsa-devel, chrome-platform

Updates cros_ec_codec maintainers.

Signed-off-by: Tzung-Bi Shih <tzungbi@google.com>
---
 .../devicetree/bindings/sound/google,cros-ec-codec.yaml          | 1 +
 MAINTAINERS                                                      | 1 +
 2 files changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
index 77adbebed824..c3e9f3485449 100644
--- a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
+++ b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
@@ -8,6 +8,7 @@ title: Audio codec controlled by ChromeOS EC
 
 maintainers:
   - Cheng-Yi Chiang <cychiang@chromium.org>
+  - Tzung-Bi Shih <tzungbi@google.com>
 
 description: |
   Google's ChromeOS EC codec is a digital mic codec provided by the
diff --git a/MAINTAINERS b/MAINTAINERS
index 568152aa9973..a1f4fd15e770 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4573,6 +4573,7 @@ F:	drivers/platform/chrome/
 
 CHROMEOS EC CODEC DRIVER
 M:	Cheng-Yi Chiang <cychiang@chromium.org>
+M:	Tzung-Bi Shih <tzungbi@google.com>
 R:	Guenter Roeck <groeck@chromium.org>
 L:	chrome-platform@lists.linux.dev
 S:	Maintained
-- 
2.35.0.263.gb82422642f-goog


^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: add self as clang reviewer
@ 2022-04-07 17:57  5% Tom Rix
  0 siblings, 0 replies; 200+ results
From: Tom Rix @ 2022-04-07 17:57 UTC (permalink / raw)
  To: nathan, ndesaulniers; +Cc: linux-kernel, llvm, Tom Rix

I have been helping with build breaks and
other clang things and would like to help
with the reviews.

Signed-off-by: Tom Rix <trix@redhat.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ebfc93d8f0d..8da670067a34 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4797,6 +4797,7 @@ F:	.clang-format
 CLANG/LLVM BUILD SUPPORT
 M:	Nathan Chancellor <nathan@kernel.org>
 M:	Nick Desaulniers <ndesaulniers@google.com>
+R:	Tom Rix <trix@redhat.com>
 L:	llvm@lists.linux.dev
 S:	Supported
 W:	https://clangbuiltlinux.github.io/
-- 
2.27.0


^ permalink raw reply related	[relevance 5%]

* [patch 9/9] MAINTAINERS: add Tom as clang reviewer
  @ 2022-04-08 20:09  5%   ` Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2022-04-08 20:09 UTC (permalink / raw)
  To: ndesaulniers, nathan, trix, akpm, patches, linux-mm, mm-commits,
	torvalds, akpm

From: Tom Rix <trix@redhat.com>
Subject: MAINTAINERS: add Tom as clang reviewer

I have been helping with build breaks and other clang things and would
like to help with the reviews.

Link: https://lkml.kernel.org/r/20220407175715.3378998-1-trix@redhat.com
Signed-off-by: Tom Rix <trix@redhat.com>
Acked-by: Nathan Chancellor <nathan@kernel.org>
Acked-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 MAINTAINERS |    1 +
 1 file changed, 1 insertion(+)

--- a/MAINTAINERS~maintainers-add-self-as-clang-reviewer
+++ a/MAINTAINERS
@@ -4791,6 +4791,7 @@ F:	.clang-format
 CLANG/LLVM BUILD SUPPORT
 M:	Nathan Chancellor <nathan@kernel.org>
 M:	Nick Desaulniers <ndesaulniers@google.com>
+R:	Tom Rix <trix@redhat.com>
 L:	llvm@lists.linux.dev
 S:	Supported
 W:	https://clangbuiltlinux.github.io/
_


^ permalink raw reply	[relevance 5%]

* [patch 9/9] MAINTAINERS: add Tom as clang reviewer
@ 2022-04-08 20:09  5%   ` Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2022-04-08 20:09 UTC (permalink / raw)
  To: ndesaulniers, nathan, trix, akpm, patches, linux-mm, mm-commits,
	torvalds, akpm

From: Tom Rix <trix@redhat.com>
Subject: MAINTAINERS: add Tom as clang reviewer

I have been helping with build breaks and other clang things and would
like to help with the reviews.

Link: https://lkml.kernel.org/r/20220407175715.3378998-1-trix@redhat.com
Signed-off-by: Tom Rix <trix@redhat.com>
Acked-by: Nathan Chancellor <nathan@kernel.org>
Acked-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 MAINTAINERS |    1 +
 1 file changed, 1 insertion(+)

--- a/MAINTAINERS~maintainers-add-self-as-clang-reviewer
+++ a/MAINTAINERS
@@ -4791,6 +4791,7 @@ F:	.clang-format
 CLANG/LLVM BUILD SUPPORT
 M:	Nathan Chancellor <nathan@kernel.org>
 M:	Nick Desaulniers <ndesaulniers@google.com>
+R:	Tom Rix <trix@redhat.com>
 L:	llvm@lists.linux.dev
 S:	Supported
 W:	https://clangbuiltlinux.github.io/
_

^ permalink raw reply	[relevance 5%]

* [PATCH] MAINTAINERS: git://github -> https://github.com for jonmason
@ 2022-10-13 21:46  5% Palmer Dabbelt
  0 siblings, 0 replies; 200+ results
From: Palmer Dabbelt @ 2022-10-13 21:46 UTC (permalink / raw)
  To: jdmason, dave.jiang, allenbh, ntb
  Cc: linux-kernel, Palmer Dabbelt, Conor Dooley

Github deprecated the git:// links about a year ago, so let's move to
the https:// URLs instead.

Reported-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://github.blog/2021-09-01-improving-git-protocol-security-github/
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
---
I've split these up by github username so folks can take them
independently, as some of these repos have been renamed at github and
thus need more than just a sed to fix them.
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index c9c396e2d8a0..796ba37dd4ff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14465,7 +14465,7 @@ M:	Allen Hubbe <allenbh@gmail.com>
 L:	ntb@lists.linux.dev
 S:	Supported
 W:	https://github.com/jonmason/ntb/wiki
-T:	git git://github.com/jonmason/ntb.git
+T:	git https://github.com/jonmason/ntb.git
 F:	drivers/net/ntb_netdev.c
 F:	drivers/ntb/
 F:	drivers/pci/endpoint/functions/pci-epf-*ntb.c
-- 
2.38.0


^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: Add entry for the Loongson LS2X I2C driver
@ 2023-02-03 10:00  5% Binbin Zhou
  0 siblings, 0 replies; 200+ results
From: Binbin Zhou @ 2023-02-03 10:00 UTC (permalink / raw)
  To: Wolfram Sang, linux-i2c, linux-kernel; +Cc: Huacai Chen, Binbin Zhou

Add myself as maintainer of the Loongson LS2X I2C driver.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 123216b76534..27b1654aa421 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12180,6 +12180,13 @@ F:	drivers/*/*loongarch*
 F:	Documentation/loongarch/
 F:	Documentation/translations/zh_CN/loongarch/
 
+LOONGSON LS2X I2C DRIVER
+M:	Binbin Zhou <zhoubinbin@loongson.cn>
+L:	linux-i2c@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml
+F:	drivers/i2c/busses/i2c-ls2x.c
+
 LOONGSON-2 SOC SERIES GUTS DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	loongarch@lists.linux.dev
-- 
2.39.0


^ permalink raw reply related	[relevance 5%]

* [PATCH mptcp-next] MAINTAINERS: Resume MPTCP co-maintainer role
@ 2023-04-18 18:57  5% Mat Martineau
  0 siblings, 0 replies; 200+ results
From: Mat Martineau @ 2023-04-18 18:57 UTC (permalink / raw)
  To: mptcp, matthieu.baerts; +Cc: Mat Martineau

I'm returning to the MPTCP maintainer role I held for most of the
subsytem's history. This time I'm using my kernel.org email address.

Signed-off-by: Mat Martineau <martineau@kernel.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1c09473685b1..6841ef90cb0e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14612,6 +14612,7 @@ F:	net/netlabel/
 
 NETWORKING [MPTCP]
 M:	Matthieu Baerts <matthieu.baerts@tessares.net>
+M:	Mat Martineau <martineau@kernel.org>
 L:	netdev@vger.kernel.org
 L:	mptcp@lists.linux.dev
 S:	Maintained
-- 
2.40.0


^ permalink raw reply related	[relevance 5%]

* [PATCH net-next] MAINTAINERS: Resume MPTCP co-maintainer role
@ 2023-04-18 23:13  5% Mat Martineau
  0 siblings, 0 replies; 200+ results
From: Mat Martineau @ 2023-04-18 23:13 UTC (permalink / raw)
  To: netdev, kuba, davem, pabeni, edumazet
  Cc: Mat Martineau, matthieu.baerts, mptcp

I'm returning to the MPTCP maintainer role I held for most of the
subsytem's history. This time I'm using my kernel.org email address.

Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Link: https://lore.kernel.org/mptcp/af85e467-8d0a-4eba-b5f8-e2f2c5d24984@tessares.net/
Signed-off-by: Mat Martineau <martineau@kernel.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4fc57dfd5fd0..e5ff4687d3f5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14612,6 +14612,7 @@ F:	net/netlabel/
 
 NETWORKING [MPTCP]
 M:	Matthieu Baerts <matthieu.baerts@tessares.net>
+M:	Mat Martineau <martineau@kernel.org>
 L:	netdev@vger.kernel.org
 L:	mptcp@lists.linux.dev
 S:	Maintained
-- 
2.40.0


^ permalink raw reply related	[relevance 5%]

* [PATCH] scripts/quilt-mail: add email address for Conor Dooley
@ 2023-06-22  8:34  5% Conor Dooley
  0 siblings, 0 replies; 200+ results
From: Conor Dooley @ 2023-06-22  8:34 UTC (permalink / raw)
  To: gregkh; +Cc: conor, conor.dooley, stable

Sometimes I miss the stable announcements cos of the delights of our
corporate email setup, so add me to the 0th mail CC list.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
I dunno how to test this, but touch wood I've not made a hames of
something trivial...

 scripts/quilt-mail | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/quilt-mail b/scripts/quilt-mail
index 5eb70af702..7b77e2970d 100755
--- a/scripts/quilt-mail
+++ b/scripts/quilt-mail
@@ -177,7 +177,8 @@ CC_NAMES=("linux-kernel@vger\.kernel\.org"
 	  "f\.fainelli@gmail\.com"
 	  "sudipm\.mukherjee@gmail\.com"
 	  "srw@sladewatkins\.net"
-	  "rwarsow@gmx\.de")
+	  "rwarsow@gmx\.de"
+	  "conor@kernel\.org")
 
 #CC_LIST="stable@vger\.kernel\.org"
 CC_LIST="patches@lists.linux.dev"
-- 
2.40.1


^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: Redo addition of ssm3515 to APPLE SOUND
@ 2023-07-12 12:15  5% Martin Povišer
  0 siblings, 0 replies; 200+ results
From: Martin Povišer @ 2023-07-12 12:15 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown; +Cc: asahi, linux-kernel, Martin Povišer

The MAINTAINERS entries added in commit 4ac690bbae02 ("ASoC: ssm3515:
Add new amp driver") were later erased in a merge commit. Re-add those.

Cc: Mark Brown <broonie@kernel.org>
Fixes: af53b00fa3ac ("Merge tag 'v6.4-rc2' into asoc-6.5 to get fixes for CI")
Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3be1bdfe8ecc..be7e662c653b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1865,9 +1865,11 @@ M:	Martin Povišer <povik+lin@cutebit.org>
 L:	asahi@lists.linux.dev
 L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:	Maintained
+F:	Documentation/devicetree/bindings/sound/adi,ssm3515.yaml
 F:	Documentation/devicetree/bindings/sound/apple,*
 F:	sound/soc/apple/*
 F:	sound/soc/codecs/cs42l83-i2c.c
+F:	sound/soc/codecs/ssm3515.c
 
 ARM/APPLE MACHINE SUPPORT
 M:	Hector Martin <marcan@marcan.st>
-- 
2.38.3


^ permalink raw reply related	[relevance 5%]

* [PATCH] Remove myself as maintainer of GFS2
@ 2023-11-14 13:57  5% Bob Peterson
  0 siblings, 0 replies; 200+ results
From: Bob Peterson @ 2023-11-14 13:57 UTC (permalink / raw)
  To: linux-fsdevel, Linus Torvalds

I am retiring from Red Hat and will no longer be a maintainer of the
gfs2 file system.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
---
 MAINTAINERS | 1 -
 1 file changed, 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index bf0f54c24f81..a45cdab67496 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8779,7 +8779,6 @@ S:	Maintained
 F:	scripts/get_maintainer.pl
 
 GFS2 FILE SYSTEM
-M:	Bob Peterson <rpeterso@redhat.com>
 M:	Andreas Gruenbacher <agruenba@redhat.com>
 L:	gfs2@lists.linux.dev
 S:	Supported
-- 
2.41.0


^ permalink raw reply related	[relevance 5%]

* [PATCH mptcp-net] MAINTAINERS: add Geliang as reviewer for MPTCP
@ 2023-12-15 14:45  5% Matthieu Baerts
  0 siblings, 0 replies; 200+ results
From: Matthieu Baerts @ 2023-12-15 14:45 UTC (permalink / raw)
  To: mptcp; +Cc: Matthieu Baerts, Geliang Tang, Mat Martineau

For a long time now, Geliang has contributed to a lot of code and
reviews related to MPTCP. So let's reflect that in the MAINTAINERS file.

This should also encourage patch submitters to add him to the CC list.

Signed-off-by: Matthieu Baerts <matttbe@kernel.org>
---

@Geliang: do you mind publicly acking this patch if you are still OK
with that?
Cc: Geliang Tang <geliang.tang@linux.dev>

@Mat: can I also add your Acked-by as discussed this week?
Cc: Mat Martineau <martineau@kernel.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 49c1caad5d99..b7e51b7b8760 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15076,6 +15076,7 @@ K:	\bmdo_
 NETWORKING [MPTCP]
 M:	Matthieu Baerts <matttbe@kernel.org>
 M:	Mat Martineau <martineau@kernel.org>
+R:	Geliang Tang <geliang.tang@linux.dev>
 L:	netdev@vger.kernel.org
 L:	mptcp@lists.linux.dev
 S:	Maintained

---
base-commit: 84d8fb414b2a78b32e97b1e4888688bca82aecf5
change-id: 20231215-mptcp-reviewers-geliang-4d826ebffd8c

Best regards,
-- 
Matthieu Baerts <matttbe@kernel.org>


^ permalink raw reply related	[relevance 5%]

* [PATCH net 1/2] MAINTAINERS: add Geliang as reviewer for MPTCP
  @ 2023-12-26 12:10  5% ` Matthieu Baerts
  0 siblings, 0 replies; 200+ results
From: Matthieu Baerts @ 2023-12-26 12:10 UTC (permalink / raw)
  To: mptcp, Mat Martineau, Geliang Tang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
  Cc: linux-kernel, netdev, Matthieu Baerts

For a long time now, Geliang has contributed to a lot of code and
reviews related to MPTCP. So let's reflect that in the MAINTAINERS file.

This should also encourage patch submitters to add him to the CC list.

Acked-by: Geliang Tang <geliang.tang@linux.dev>
Acked-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts <matttbe@kernel.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7cef2d2ef8d7..cc9e2dc4ad9a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15078,6 +15078,7 @@ K:	\bmdo_
 NETWORKING [MPTCP]
 M:	Matthieu Baerts <matttbe@kernel.org>
 M:	Mat Martineau <martineau@kernel.org>
+R:	Geliang Tang <geliang.tang@linux.dev>
 L:	netdev@vger.kernel.org
 L:	mptcp@lists.linux.dev
 S:	Maintained

-- 
2.43.0


^ permalink raw reply related	[relevance 5%]

* [PATCH dlm/next] MAINTAINERS: update DLM git repository entry
@ 2024-02-05 15:48  5% Alexander Aring
  0 siblings, 0 replies; 200+ results
From: Alexander Aring @ 2024-02-05 15:48 UTC (permalink / raw)
  To: teigland; +Cc: gfs2, aahringo

This patch updates the DLM git repository url to the new one that is
created under the DLM shared space to join the effort between the
current DLM maintainers.

Signed-off-by: Alexander Aring <aahringo@redhat.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 960512bec428..05a201bb296a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6244,7 +6244,7 @@ M:	David Teigland <teigland@redhat.com>
 L:	gfs2@lists.linux.dev
 S:	Supported
 W:	https://pagure.io/dlm
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/dlm/linux-dlm.git
 F:	fs/dlm/
 
 DMA BUFFER SHARING FRAMEWORK
-- 
2.43.0


^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: Change lingshan's email to kernel.org
@ 2024-05-13 21:27  5% Zhu Lingshan
  0 siblings, 0 replies; 200+ results
From: Zhu Lingshan @ 2024-05-13 21:27 UTC (permalink / raw)
  To: jasowang, mst; +Cc: lingshan.zhu, virtualization, Zhu Lingshan

This commit changes lingshan's email from intel.com
to kernel.org.

This commit also changes the title since ifcvf drives
standard virtio pci devices now.

Signed-off-by: Zhu Lingshan <lingshan.zhu@intel.com>
---
 MAINTAINERS | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index d75527f7bb0d..b69239cf30a3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10465,8 +10465,8 @@ F:	include/net/nl802154.h
 F:	net/ieee802154/
 F:	net/mac802154/
 
-Intel VIRTIO DATA PATH ACCELERATOR
-M:	Zhu Lingshan <lingshan.zhu@intel.com>
+Intel AND STANDARD VIRTIO DATA PATH ACCELERATOR
+M:	Zhu Lingshan <lingshan.zhu@kernel.org>
 L:	virtualization@lists.linux.dev
 S:	Supported
 F:	drivers/vdpa/ifcvf/
-- 
2.43.0


^ permalink raw reply related	[relevance 5%]

* [PATCH V2] MAINTAINERS: Change lingshan's email to kernel.org
@ 2024-05-14 16:51  5% Zhu Lingshan
  0 siblings, 0 replies; 200+ results
From: Zhu Lingshan @ 2024-05-14 16:51 UTC (permalink / raw)
  To: jasowang, mst; +Cc: lingshan.zhu, virtualization, Zhu Lingshan

This commit changes lingshan's email from intel.com
to kernel.org.

Signed-off-by: Zhu Lingshan <lingshan.zhu@intel.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index d75527f7bb0d..501b81b61b6d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10466,7 +10466,7 @@ F:	net/ieee802154/
 F:	net/mac802154/
 
 Intel VIRTIO DATA PATH ACCELERATOR
-M:	Zhu Lingshan <lingshan.zhu@intel.com>
+M:	Zhu Lingshan <lingshan.zhu@kernel.org>
 L:	virtualization@lists.linux.dev
 S:	Supported
 F:	drivers/vdpa/ifcvf/
-- 
2.43.0


^ permalink raw reply related	[relevance 5%]

* [PATCH 06/10] platform/chrome: cros_ec_typec: Move structs to header
  @ 2022-12-28  0:45  5% ` Prashant Malani
  0 siblings, 0 replies; 200+ results
From: Prashant Malani @ 2022-12-28  0:45 UTC (permalink / raw)
  To: linux-kernel, chrome-platform
  Cc: heikki.krogerus, Prashant Malani, Benson Leung, Daisuke Nojiri,
	Dustin L. Howett, Evan Green, Greg Kroah-Hartman, Guenter Roeck,
	Gustavo A. R. Silva, Lee Jones, Lee Jones, Sebastian Reichel,
	Stephen Boyd, Tinghan Shen, Tzung-Bi Shih, Xiang wangx

Move ChromeOS Type-C structs into their own header, so they can be
referenced by other files which can be added to the same module.

No functional changes introduced by this patch.

Signed-off-by: Prashant Malani <pmalani@chromium.org>
---
 MAINTAINERS                             |  2 +-
 drivers/platform/chrome/cros_ec_typec.c | 78 +----------------------
 drivers/platform/chrome/cros_ec_typec.h | 85 +++++++++++++++++++++++++
 3 files changed, 88 insertions(+), 77 deletions(-)
 create mode 100644 drivers/platform/chrome/cros_ec_typec.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f61eb221415b..8219b646ab50 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4998,7 +4998,7 @@ CHROMEOS EC USB TYPE-C DRIVER
 M:	Prashant Malani <pmalani@chromium.org>
 L:	chrome-platform@lists.linux.dev
 S:	Maintained
-F:	drivers/platform/chrome/cros_ec_typec.c
+F:	drivers/platform/chrome/cros_ec_typec.*
 F:	drivers/platform/chrome/cros_typec_switch.c
 
 CHROMEOS EC USB PD NOTIFY DRIVER
diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
index 665fa76e2416..a4eff590ca56 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -7,96 +7,22 @@
  */
 
 #include <linux/acpi.h>
-#include <linux/list.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_data/cros_ec_commands.h>
-#include <linux/platform_data/cros_ec_proto.h>
 #include <linux/platform_data/cros_usbpd_notify.h>
 #include <linux/platform_device.h>
-#include <linux/usb/pd.h>
 #include <linux/usb/pd_vdo.h>
-#include <linux/usb/typec.h>
-#include <linux/usb/typec_altmode.h>
 #include <linux/usb/typec_dp.h>
-#include <linux/usb/typec_mux.h>
-#include <linux/usb/typec_retimer.h>
 #include <linux/usb/typec_tbt.h>
-#include <linux/usb/role.h>
+
+#include "cros_ec_typec.h"
 
 #define DRV_NAME "cros-ec-typec"
 
 #define DP_PORT_VDO	(DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \
 				DP_CAP_DFP_D | DP_CAP_RECEPTACLE)
 
-/* Supported alt modes. */
-enum {
-	CROS_EC_ALTMODE_DP = 0,
-	CROS_EC_ALTMODE_TBT,
-	CROS_EC_ALTMODE_MAX,
-};
-
-/* Container for altmode pointer nodes. */
-struct cros_typec_altmode_node {
-	struct typec_altmode *amode;
-	struct list_head list;
-};
-
-/* Per port data. */
-struct cros_typec_port {
-	struct typec_port *port;
-	int port_num;
-	/* Initial capabilities for the port. */
-	struct typec_capability caps;
-	struct typec_partner *partner;
-	struct typec_cable *cable;
-	/* SOP' plug. */
-	struct typec_plug *plug;
-	/* Port partner PD identity info. */
-	struct usb_pd_identity p_identity;
-	/* Port cable PD identity info. */
-	struct usb_pd_identity c_identity;
-	struct typec_switch *ori_sw;
-	struct typec_mux *mux;
-	struct typec_retimer *retimer;
-	struct usb_role_switch *role_sw;
-
-	/* Variables keeping track of switch state. */
-	struct typec_mux_state state;
-	uint8_t mux_flags;
-	uint8_t role;
-
-	struct typec_altmode *port_altmode[CROS_EC_ALTMODE_MAX];
-
-	/* Flag indicating that PD partner discovery data parsing is completed. */
-	bool sop_disc_done;
-	bool sop_prime_disc_done;
-	struct ec_response_typec_discovery *disc_data;
-	struct list_head partner_mode_list;
-	struct list_head plug_mode_list;
-
-	/* PDO-related structs */
-	struct usb_power_delivery *partner_pd;
-	struct usb_power_delivery_capabilities *partner_src_caps;
-	struct usb_power_delivery_capabilities *partner_sink_caps;
-
-	struct cros_typec_data *typec_data;
-};
-
-/* Platform-specific data for the Chrome OS EC Type C controller. */
-struct cros_typec_data {
-	struct device *dev;
-	struct cros_ec_device *ec;
-	int num_ports;
-	unsigned int pd_ctrl_ver;
-	/* Array of ports, indexed by port number. */
-	struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
-	struct notifier_block nb;
-	struct work_struct port_work;
-	bool typec_cmd_supported;
-	bool needs_mux_ack;
-};
-
 static int cros_typec_parse_port_props(struct typec_capability *cap,
 				       struct fwnode_handle *fwnode,
 				       struct device *dev)
diff --git a/drivers/platform/chrome/cros_ec_typec.h b/drivers/platform/chrome/cros_ec_typec.h
new file mode 100644
index 000000000000..deda180a646f
--- /dev/null
+++ b/drivers/platform/chrome/cros_ec_typec.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __CROS_EC_TYPEC__
+#define __CROS_EC_TYPEC__
+
+#include <linux/list.h>
+#include <linux/notifier.h>
+#include <linux/platform_data/cros_ec_proto.h>
+#include <linux/usb/pd.h>
+#include <linux/usb/role.h>
+#include <linux/usb/typec.h>
+#include <linux/usb/typec_altmode.h>
+#include <linux/usb/typec_mux.h>
+#include <linux/usb/typec_retimer.h>
+#include <linux/workqueue.h>
+
+/* Supported alt modes. */
+enum {
+	CROS_EC_ALTMODE_DP = 0,
+	CROS_EC_ALTMODE_TBT,
+	CROS_EC_ALTMODE_MAX,
+};
+
+/* Container for altmode pointer nodes. */
+struct cros_typec_altmode_node {
+	struct typec_altmode *amode;
+	struct list_head list;
+};
+
+/* Platform-specific data for the Chrome OS EC Type C controller. */
+struct cros_typec_data {
+	struct device *dev;
+	struct cros_ec_device *ec;
+	int num_ports;
+	unsigned int pd_ctrl_ver;
+	/* Array of ports, indexed by port number. */
+	struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
+	struct notifier_block nb;
+	struct work_struct port_work;
+	bool typec_cmd_supported;
+	bool needs_mux_ack;
+};
+
+/* Per port data. */
+struct cros_typec_port {
+	struct typec_port *port;
+	int port_num;
+	/* Initial capabilities for the port. */
+	struct typec_capability caps;
+	struct typec_partner *partner;
+	struct typec_cable *cable;
+	/* SOP' plug. */
+	struct typec_plug *plug;
+	/* Port partner PD identity info. */
+	struct usb_pd_identity p_identity;
+	/* Port cable PD identity info. */
+	struct usb_pd_identity c_identity;
+	struct typec_switch *ori_sw;
+	struct typec_mux *mux;
+	struct typec_retimer *retimer;
+	struct usb_role_switch *role_sw;
+
+	/* Variables keeping track of switch state. */
+	struct typec_mux_state state;
+	uint8_t mux_flags;
+	uint8_t role;
+
+	struct typec_altmode *port_altmode[CROS_EC_ALTMODE_MAX];
+
+	/* Flag indicating that PD partner discovery data parsing is completed. */
+	bool sop_disc_done;
+	bool sop_prime_disc_done;
+	struct ec_response_typec_discovery *disc_data;
+	struct list_head partner_mode_list;
+	struct list_head plug_mode_list;
+
+	/* PDO-related structs */
+	struct usb_power_delivery *partner_pd;
+	struct usb_power_delivery_capabilities *partner_src_caps;
+	struct usb_power_delivery_capabilities *partner_sink_caps;
+
+	struct cros_typec_data *typec_data;
+};
+
+#endif /*  __CROS_EC_TYPEC__ */
-- 
2.39.0.314.g84b9a713c41-goog


^ permalink raw reply related	[relevance 5%]

* [PATCH v1 2/2] dt-bindings: soc: add loongson2 guts
  2022-10-24 10:58  6% [PATCH v1 1/2] soc: loongson: add GUTS driver for loongson2 platforms Yinbo Zhu
@ 2022-10-24 10:58  5% ` Yinbo Zhu
  0 siblings, 0 replies; 200+ results
From: Yinbo Zhu @ 2022-10-24 10:58 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, Yinbo Zhu

Add the loongson2 soc guts driver binding with DT schema format
using json-schema.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
---
 .../soc/loongson/loongson,ls2k-guts.yaml      | 37 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/loongson/loongson,ls2k-guts.yaml

diff --git a/Documentation/devicetree/bindings/soc/loongson/loongson,ls2k-guts.yaml b/Documentation/devicetree/bindings/soc/loongson/loongson,ls2k-guts.yaml
new file mode 100644
index 000000000000..2502f8aeb74d
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/loongson/loongson,ls2k-guts.yaml
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/loongson/loongson,ls2k-guts.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson2 GUTS driver.
+
+maintainers:
+  - Yinbo Zhu <zhuyinbo@loongson.cn>
+
+description: |
+  GUTS driver was to manage and access global utilities block. Initially
+  only reading SVR and registering soc device are supported.
+
+properties:
+  compatible:
+    const: loongson,ls2k-guts
+
+  reg:
+    maxItems: 1
+
+  little-endian: true
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    guts: guts@1fe00000 {
+        compatible = "loongson,ls2k-guts";
+        reg = <0x1fe00000 0x3ffc>;
+        little-endian;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index f032096d5251..d315237692ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11934,6 +11934,7 @@ LOONGSON2 SOC SERIES GUTS DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	loongarch@lists.linux.dev
 S:	Maintained
+F:	Documentation/devicetree/bindings/soc/loongson/loongson,ls2k-guts.yaml
 F:	drivers/soc/loongson/loongson2_guts.c
 F:	include/linux/loongson/loongson2_guts.h
 
-- 
2.20.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v2 2/3] mm/damon/Kconfig: add DAMON debugfs interface deprecation notice
  @ 2023-02-10  4:48  5% ` SeongJae Park
  2023-02-10  4:48  5% ` [PATCH v2 3/3] mm/damon/dbgfs: print DAMON debugfs interface deprecation message SeongJae Park
  1 sibling, 0 replies; 200+ results
From: SeongJae Park @ 2023-02-10  4:48 UTC (permalink / raw)
  To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel

DAMON debugfs interface has announced to be deprecated after >v5.15 LTS
kernel is released.  And, v6.1.y has announced to be an LTS[1].

Though the announcement was there for a while, some people might not
noticed that so far.  Also, some users could depend on it and have
problems at  movng to the alternative (DAMON sysfs interface).

For such cases, note DAMON debugfs interface as deprecated, and contacts
to ask helps on the Kconfig.

[1] https://git.kernel.org/pub/scm/docs/kernel/website.git/commit/?id=332e9121320bc7461b2d3a79665caf153e51732c

Signed-off-by: SeongJae Park <sj@kernel.org>
---
 mm/damon/Kconfig | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/mm/damon/Kconfig b/mm/damon/Kconfig
index 7821fcb3f258..436c6b4cb5ec 100644
--- a/mm/damon/Kconfig
+++ b/mm/damon/Kconfig
@@ -60,7 +60,7 @@ config DAMON_SYSFS
 	  the interface for arbitrary data access monitoring.
 
 config DAMON_DBGFS
-	bool "DAMON debugfs interface"
+	bool "DAMON debugfs interface (DEPRECATED!)"
 	depends on DAMON_VADDR && DAMON_PADDR && DEBUG_FS
 	help
 	  This builds the debugfs interface for DAMON.  The user space admins
@@ -68,8 +68,9 @@ config DAMON_DBGFS
 
 	  If unsure, say N.
 
-	  This will be removed after >5.15.y LTS kernel is released, so users
-	  should move to the sysfs interface (DAMON_SYSFS).
+	  This is deprecated, so users should move to the sysfs interface
+	  (DAMON_SYSFS).  If you depend on this and cannot move, please report
+	  your usecase to damon@lists.linux.dev and linux-mm@kvack.org.
 
 config DAMON_DBGFS_KUNIT_TEST
 	bool "Test for damon debugfs interface" if !KUNIT_ALL_TESTS
-- 
2.25.1


^ permalink raw reply related	[relevance 5%]

* [PATCH] MAINTAINERS: Add a general "kernel hardening" section
@ 2022-07-02  0:46  5% Kees Cook
  0 siblings, 0 replies; 200+ results
From: Kees Cook @ 2022-07-02  0:46 UTC (permalink / raw)
  To: keescook
  Cc: Nathan Chancellor, Nick Desaulniers, Tom Rix, linux-kernel, llvm,
	linux-hardening

While many large subsystems related to kernel hardening have their own
distinct MAINTAINERS entries, there are some smaller collections that
don't, but are maintained/reviewed by linux-hardening@vger.kernel.org.
Add a section to capture these, add (or replace defunct) trees that are
now all carried in the hardening tree.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 MAINTAINERS | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3cf9842d9233..2702b29e922f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4873,7 +4873,7 @@ R:	Nick Desaulniers <ndesaulniers@google.com>
 L:	llvm@lists.linux.dev
 S:	Supported
 B:	https://github.com/ClangBuiltLinux/linux/issues
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/clang/features
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
 F:	include/linux/cfi.h
 F:	kernel/cfi.c
 
@@ -7783,6 +7783,7 @@ FORTIFY_SOURCE
 M:	Kees Cook <keescook@chromium.org>
 L:	linux-hardening@vger.kernel.org
 S:	Supported
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
 F:	include/linux/fortify-string.h
 F:	lib/test_fortify/*
 F:	scripts/test_fortify.sh
@@ -8225,6 +8226,7 @@ GCC PLUGINS
 M:	Kees Cook <keescook@chromium.org>
 L:	linux-hardening@vger.kernel.org
 S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
 F:	Documentation/kbuild/gcc-plugins.rst
 F:	scripts/Makefile.gcc-plugins
 F:	scripts/gcc-plugins/
@@ -10742,6 +10744,17 @@ F:	scripts/mk*
 F:	scripts/mod/
 F:	scripts/package/
 
+KERNEL HARDENING (not covered by other areas)
+M:	Kees Cook <keescook@chromium.org>
+L:	linux-hardening@vger.kernel.org
+S:	Supported
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
+F:	include/linux/overflow.h
+F:	include/linux/randomize_kstack.h
+F:	mm/usercopy.c
+K:	\b(add|choose)_random_kstack_offset\b
+K:	\b__check_(object_size|heap_object)\b
+
 KERNEL JANITORS
 L:	kernel-janitors@vger.kernel.org
 S:	Odd Fixes
@@ -11542,7 +11555,7 @@ F:	drivers/media/usb/dvb-usb-v2/lmedm04*
 LOADPIN SECURITY MODULE
 M:	Kees Cook <keescook@chromium.org>
 S:	Supported
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git lsm/loadpin
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
 F:	Documentation/admin-guide/LSM/LoadPin.rst
 F:	security/loadpin/
 
@@ -17857,7 +17870,7 @@ M:	Kees Cook <keescook@chromium.org>
 R:	Andy Lutomirski <luto@amacapital.net>
 R:	Will Drewry <wad@chromium.org>
 S:	Supported
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git seccomp
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/seccomp
 F:	Documentation/userspace-api/seccomp_filter.rst
 F:	include/linux/seccomp.h
 F:	include/uapi/linux/seccomp.h
@@ -21993,7 +22006,7 @@ F:	include/linux/yam.h
 YAMA SECURITY MODULE
 M:	Kees Cook <keescook@chromium.org>
 S:	Supported
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
 F:	Documentation/admin-guide/LSM/Yama.rst
 F:	security/yama/
 
-- 
2.32.0


^ permalink raw reply related	[relevance 5%]

* [PATCH 2/3] mm/damon/Kconfig: add DAMON debugfs interface deprecation notice
  @ 2023-02-09 19:20  5% ` SeongJae Park
  2023-02-09 19:20  5% ` [PATCH 3/3] mm/damon/dbgfs: print DAMON debugfs interface deprecation message SeongJae Park
  1 sibling, 0 replies; 200+ results
From: SeongJae Park @ 2023-02-09 19:20 UTC (permalink / raw)
  To: Andrew Morton; +Cc: SeongJae Park, damon, linux-mm, linux-kernel

DAMON debugfs interface has announced to be deprecated after >v5.15 LTS
kernel is released.  And, v6.1.y has announced to be an LTS[1].

Though the announcement was there for a while, some people might not
noticed that so far.  Also, some users could depend on it and have
problems at  movng to the alternative (DAMON sysfs interface).

For such cases, note DAMON debugfs interface as deprecated, and contacts
to ask helps on the Kconfig.

[1] https://git.kernel.org/pub/scm/docs/kernel/website.git/commit/?id=332e9121320bc7461b2d3a79665caf153e51732c

Signed-off-by: SeongJae Park <sj@kernel.org>
---
 mm/damon/Kconfig | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/mm/damon/Kconfig b/mm/damon/Kconfig
index 7821fcb3f258..436c6b4cb5ec 100644
--- a/mm/damon/Kconfig
+++ b/mm/damon/Kconfig
@@ -60,7 +60,7 @@ config DAMON_SYSFS
 	  the interface for arbitrary data access monitoring.
 
 config DAMON_DBGFS
-	bool "DAMON debugfs interface"
+	bool "DAMON debugfs interface (DEPRECATED!)"
 	depends on DAMON_VADDR && DAMON_PADDR && DEBUG_FS
 	help
 	  This builds the debugfs interface for DAMON.  The user space admins
@@ -68,8 +68,9 @@ config DAMON_DBGFS
 
 	  If unsure, say N.
 
-	  This will be removed after >5.15.y LTS kernel is released, so users
-	  should move to the sysfs interface (DAMON_SYSFS).
+	  This is deprecated, so users should move to the sysfs interface
+	  (DAMON_SYSFS).  If you depend on this and cannot move, please report
+	  your usecase to damon@lists.linux.dev and linux-mm@kvack.org.
 
 config DAMON_DBGFS_KUNIT_TEST
 	bool "Test for damon debugfs interface" if !KUNIT_ALL_TESTS
-- 
2.25.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v7 1/2] soc: loongson: add GUTS driver for loongson-2 platforms
@ 2022-11-11  5:42  5% Yinbo Zhu
  2022-11-11  5:42  5% ` [PATCH v7 2/2] dt-bindings: soc: add loongson-2 chipid Yinbo Zhu
  0 siblings, 1 reply; 200+ results
From: Yinbo Zhu @ 2022-11-11  5:42 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, soc, Yinbo Zhu

The global utilities block controls PCIE device enabling, alternate
function selection for multiplexed signals, consistency of HDA, USB
and PCIE, configuration of memory controller, rtc controller, lio
controller, and clock control.

This patch adds a driver to manage and access global utilities block
for LoongArch architecture Loongson-2 SoCs. Initially only reading SVR
and registering soc device are supported. Other guts accesses, such
as reading firmware configuration by default, should eventually be
added into this driver as well.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
---
Change in v7:
		1. Replace LA/loongarch with LoongArch.
		2. Replace PMON with firmware.
		3. Add MODULE_LICENSE and MODULE_DESCRIPTION in driver ending.
Change in v6:
		1. Add full name spelling about GUTS in Kconfig.
		2. Add reviewed-by information.
Change in v5:
		1. Add all history change log information.
Change in v4:
		1. Remove menu information in Kconfig.
Change in v3:
		1. Replace string loongson2/Loongson2 with Loongson-2/loongson-2
	           in commit message, Kconfig, Makefile file.
		2. Replace string LOONGSON2 with LOONGSON-2.
Change in v2:
		1. Add architecture support commit log description.
		2. Add other guts accesses plan commit log description.
		3. Add "depends on LOONGARCH || COMPILE_TEST" for
		   LOONGSON2_GUTS in Kconfig.
		4. Move the scfg_guts to .c file from .h and delete .h.
		5. Remove __packed on scfg_guts.

 MAINTAINERS                           |   6 +
 drivers/soc/Kconfig                   |   1 +
 drivers/soc/Makefile                  |   1 +
 drivers/soc/loongson/Kconfig          |  18 +++
 drivers/soc/loongson/Makefile         |   6 +
 drivers/soc/loongson/loongson2_guts.c | 192 ++++++++++++++++++++++++++
 6 files changed, 224 insertions(+)
 create mode 100644 drivers/soc/loongson/Kconfig
 create mode 100644 drivers/soc/loongson/Makefile
 create mode 100644 drivers/soc/loongson/loongson2_guts.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c4fc50eb260b..99aa2cb9c80a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12044,6 +12044,12 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
 F:	drivers/pinctrl/pinctrl-loongson2.c
 
+LOONGSON-2 SOC SERIES GUTS DRIVER
+M:	Yinbo Zhu <zhuyinbo@loongson.cn>
+L:	loongarch@lists.linux.dev
+S:	Maintained
+F:	drivers/soc/loongson/loongson2_guts.c
+
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
 M:	Sathya Prakash <sathya.prakash@broadcom.com>
 M:	Sreekanth Reddy <sreekanth.reddy@broadcom.com>
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index e461c071189b..5dbb09f843f7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -13,6 +13,7 @@ source "drivers/soc/fujitsu/Kconfig"
 source "drivers/soc/imx/Kconfig"
 source "drivers/soc/ixp4xx/Kconfig"
 source "drivers/soc/litex/Kconfig"
+source "drivers/soc/loongson/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/microchip/Kconfig"
 source "drivers/soc/pxa/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 69ba6508cf2c..fff513bd522d 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -18,6 +18,7 @@ obj-y				+= imx/
 obj-y				+= ixp4xx/
 obj-$(CONFIG_SOC_XWAY)		+= lantiq/
 obj-$(CONFIG_LITEX_SOC_CONTROLLER) += litex/
+obj-y				+= loongson/
 obj-y				+= mediatek/
 obj-y				+= microchip/
 obj-y				+= pxa/
diff --git a/drivers/soc/loongson/Kconfig b/drivers/soc/loongson/Kconfig
new file mode 100644
index 000000000000..707f56358dc4
--- /dev/null
+++ b/drivers/soc/loongson/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Loongson-2 series SoC drivers
+#
+
+config LOONGSON2_GUTS
+	tristate "Loongson-2 SoC Global UtiliTieS (GUTS) register block"
+	depends on LOONGARCH || COMPILE_TEST
+	select SOC_BUS
+	help
+	 The global utilities block controls PCIE device enabling, alternate
+	 function selection for multiplexed signals, consistency of HDA, USB
+	 and PCIE, configuration of memory controller, rtc controller, lio
+	 controller, and clock control. This patch adds a driver to manage
+	 and access global utilities block for LoongArch architecture Loongson-2
+	 SoCs. Initially only reading SVR and registering soc device are
+	 supported. Other guts accesses, such as reading firmware configuration
+	 by default, should eventually be added into this driver as well.
diff --git a/drivers/soc/loongson/Makefile b/drivers/soc/loongson/Makefile
new file mode 100644
index 000000000000..263c486df638
--- /dev/null
+++ b/drivers/soc/loongson/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Makefile for the Linux Kernel SoC Loongson-2 specific device drivers
+#
+
+obj-$(CONFIG_LOONGSON2_GUTS)		+= loongson2_guts.o
diff --git a/drivers/soc/loongson/loongson2_guts.c b/drivers/soc/loongson/loongson2_guts.c
new file mode 100644
index 000000000000..bace4bc8e03b
--- /dev/null
+++ b/drivers/soc/loongson/loongson2_guts.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Author: Yinbo Zhu <zhuyinbo@loongson.cn>
+ * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/sys_soc.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+static struct soc_device_attribute soc_dev_attr;
+static struct soc_device *soc_dev;
+
+/*
+ * Global Utility Registers.
+ *
+ * Not all registers defined in this structure are available on all chips, so
+ * you are expected to know whether a given register actually exists on your
+ * chip before you access it.
+ *
+ * Also, some registers are similar on different chips but have slightly
+ * different names.  In these cases, one name is chosen to avoid extraneous
+ * #ifdefs.
+ */
+struct scfg_guts {
+	u32     svr;            /* Version Register */
+	u8      res0[4];
+	u16     feature;        /* Feature Register */
+	u32     vendor;         /* Vendor Register */
+	u8      res1[6];
+	u32     id;
+	u8      res2[0x3ff8 - 0x18];
+	u32     chip;
+};
+
+static struct guts {
+	struct scfg_guts __iomem *regs;
+	bool little_endian;
+} *guts;
+
+struct loongson2_soc_die_attr {
+	char	*die;
+	u32	svr;
+	u32	mask;
+};
+
+/* SoC die attribute definition for Loongson-2 platform */
+static const struct loongson2_soc_die_attr loongson2_soc_die[] = {
+
+	/*
+	 * LoongArch-based SoCs Loongson-2 Series
+	 */
+
+	/* Die: 2k1000, SoC: 2k1000 */
+	{ .die		= "2K1000",
+	  .svr		= 0x00000013,
+	  .mask		= 0x000000ff,
+	},
+	{ },
+};
+
+static const struct loongson2_soc_die_attr *loongson2_soc_die_match(
+	u32 svr, const struct loongson2_soc_die_attr *matches)
+{
+	while (matches->svr) {
+		if (matches->svr == (svr & matches->mask))
+			return matches;
+		matches++;
+	};
+
+	return NULL;
+}
+
+static u32 loongson2_guts_get_svr(void)
+{
+	u32 svr = 0;
+
+	if (!guts || !guts->regs)
+		return svr;
+
+	if (guts->little_endian)
+		svr = ioread32(&guts->regs->svr);
+	else
+		svr = ioread32be(&guts->regs->svr);
+
+	return svr;
+}
+
+static int loongson2_guts_probe(struct platform_device *pdev)
+{
+	struct device_node *root, *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	const struct loongson2_soc_die_attr *soc_die;
+	const char *machine;
+	u32 svr;
+
+	/* Initialize guts */
+	guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
+	if (!guts)
+		return -ENOMEM;
+
+	guts->little_endian = of_property_read_bool(np, "little-endian");
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	guts->regs = ioremap(res->start, res->end - res->start + 1);
+	if (IS_ERR(guts->regs))
+		return PTR_ERR(guts->regs);
+
+	/* Register soc device */
+	root = of_find_node_by_path("/");
+	if (of_property_read_string(root, "model", &machine))
+		of_property_read_string_index(root, "compatible", 0, &machine);
+	of_node_put(root);
+	if (machine)
+		soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+
+	svr = loongson2_guts_get_svr();
+	soc_die = loongson2_soc_die_match(svr, loongson2_soc_die);
+	if (soc_die) {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL,
+						     "Loongson %s", soc_die->die);
+	} else {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "Loongson");
+	}
+	if (!soc_dev_attr.family)
+		return -ENOMEM;
+	soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL,
+					     "svr:0x%08x", svr);
+	if (!soc_dev_attr.soc_id)
+		return -ENOMEM;
+	soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
+					       (svr >>  4) & 0xf, svr & 0xf);
+	if (!soc_dev_attr.revision)
+		return -ENOMEM;
+
+	soc_dev = soc_device_register(&soc_dev_attr);
+	if (IS_ERR(soc_dev))
+		return PTR_ERR(soc_dev);
+
+	pr_info("Machine: %s\n", soc_dev_attr.machine);
+	pr_info("SoC family: %s\n", soc_dev_attr.family);
+	pr_info("SoC ID: %s, Revision: %s\n",
+		soc_dev_attr.soc_id, soc_dev_attr.revision);
+
+	return 0;
+}
+
+static int loongson2_guts_remove(struct platform_device *dev)
+{
+	soc_device_unregister(soc_dev);
+
+	return 0;
+}
+
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for Loongson-2 SoCs.
+ */
+static const struct of_device_id loongson2_guts_of_match[] = {
+	{ .compatible = "loongson,ls2k-chipid", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, loongson2_guts_of_match);
+
+static struct platform_driver loongson2_guts_driver = {
+	.driver = {
+		.name = "loongson2-guts",
+		.of_match_table = loongson2_guts_of_match,
+	},
+	.probe = loongson2_guts_probe,
+	.remove = loongson2_guts_remove,
+};
+
+static int __init loongson2_guts_init(void)
+{
+	return platform_driver_register(&loongson2_guts_driver);
+}
+core_initcall(loongson2_guts_init);
+
+static void __exit loongson2_guts_exit(void)
+{
+	platform_driver_unregister(&loongson2_guts_driver);
+}
+module_exit(loongson2_guts_exit);
+
+MODULE_DESCRIPTION("Loongson2 GUTS driver");
+MODULE_LICENSE("GPL");
-- 
2.20.1


^ permalink raw reply related	[relevance 5%]

* [merged mm-stable] maintainers-damon-link-maintainer-profile-git-trees-and-website.patch removed from -mm tree
@ 2023-02-03  6:35  5% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2023-02-03  6:35 UTC (permalink / raw)
  To: mm-commits, shuah, corbet, sj, akpm


The quilt patch titled
     Subject: MAINTAINERS/DAMON: link maintainer profile, git trees, and website
has been removed from the -mm tree.  Its filename was
     maintainers-damon-link-maintainer-profile-git-trees-and-website.patch

This patch was dropped because it was merged into the mm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: MAINTAINERS/DAMON: link maintainer profile, git trees, and website
Date: Tue, 10 Jan 2023 19:03:58 +0000

Add links to below DAMON development related resource to DAMON section in
MAINTAINERS file.

- The basic policies and expectations of DAMON development,
- DAMON development trees, and
- DAMON introduction website.

Link: https://lkml.kernel.org/r/20230110190400.119388-7-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---


--- a/MAINTAINERS~maintainers-damon-link-maintainer-profile-git-trees-and-website
+++ a/MAINTAINERS
@@ -5790,6 +5790,11 @@ M:	SeongJae Park <sj@kernel.org>
 L:	damon@lists.linux.dev
 L:	linux-mm@kvack.org
 S:	Maintained
+W:	https://damonitor.github.io
+P:	Documentation/mm/damon/maintainer-profile.rst
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
+T:	quilt git://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/sj/linux.git damon/next
 F:	Documentation/ABI/testing/sysfs-kernel-mm-damon
 F:	Documentation/admin-guide/mm/damon/
 F:	Documentation/mm/damon/
_

Patches currently in -mm which might be from sj@kernel.org are

scripts-spelling-add-a-few-more-typos.patch


^ permalink raw reply	[relevance 5%]

* [PATCH v6 1/2] soc: loongson: add GUTS driver for loongson-2 platforms
@ 2022-11-04  2:48  5% Yinbo Zhu
  2022-11-04  2:48  5% ` [PATCH v6 2/2] dt-bindings: soc: add loongson-2 chipid Yinbo Zhu
  0 siblings, 1 reply; 200+ results
From: Yinbo Zhu @ 2022-11-04  2:48 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, soc, Yinbo Zhu

The global utilities block controls PCIE device enabling, alternate
function selection for multiplexed signals, consistency of HDA, USB
and PCIE, configuration of memory controller, rtc controller, lio
controller, and clock control.

This patch adds a driver to manage and access global utilities block
for loongarch architecture Loongson-2 SoCs. Initially only reading SVR
and registering soc device are supported. Other guts accesses, such
as reading PMON configuration by default, should eventually be added
into this driver as well.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
---
Change in v6:
		1. Add full name spelling about GUTS in Kconfig.
		2. Add reviewed-by information.
Change in v5:
		1. Add all history change log information.
Change in v4:
		1. Remove menu information in Kconfig.
Change in v3:
		1. Replace string loongson2/Loongson2 with Loongson-2/loongson-2
	           in commit message, Kconfig, Makefile file.
		2. Replace string LOONGSON2 with LOONGSON-2.
Change in v2:
		1. Add architecture support commit log description.
		2. Add other guts accesses plan commit log description.
		3. Add "depends on LOONGARCH || COMPILE_TEST" for
		   LOONGSON2_GUTS in Kconfig.
		4. Move the scfg_guts to .c file from .h and delete .h.
		5. Remove __packed on scfg_guts.

 MAINTAINERS                           |   6 +
 drivers/soc/Kconfig                   |   1 +
 drivers/soc/Makefile                  |   1 +
 drivers/soc/loongson/Kconfig          |  18 +++
 drivers/soc/loongson/Makefile         |   6 +
 drivers/soc/loongson/loongson2_guts.c | 189 ++++++++++++++++++++++++++
 6 files changed, 221 insertions(+)
 create mode 100644 drivers/soc/loongson/Kconfig
 create mode 100644 drivers/soc/loongson/Makefile
 create mode 100644 drivers/soc/loongson/loongson2_guts.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c9dc5ddbd9fe..20ce056ae207 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12041,6 +12041,12 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
 F:	drivers/pinctrl/pinctrl-loongson2.c
 
+LOONGSON-2 SOC SERIES GUTS DRIVER
+M:	Yinbo Zhu <zhuyinbo@loongson.cn>
+L:	loongarch@lists.linux.dev
+S:	Maintained
+F:	drivers/soc/loongson/loongson2_guts.c
+
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
 M:	Sathya Prakash <sathya.prakash@broadcom.com>
 M:	Sreekanth Reddy <sreekanth.reddy@broadcom.com>
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index e461c071189b..5dbb09f843f7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -13,6 +13,7 @@ source "drivers/soc/fujitsu/Kconfig"
 source "drivers/soc/imx/Kconfig"
 source "drivers/soc/ixp4xx/Kconfig"
 source "drivers/soc/litex/Kconfig"
+source "drivers/soc/loongson/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/microchip/Kconfig"
 source "drivers/soc/pxa/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 69ba6508cf2c..fff513bd522d 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -18,6 +18,7 @@ obj-y				+= imx/
 obj-y				+= ixp4xx/
 obj-$(CONFIG_SOC_XWAY)		+= lantiq/
 obj-$(CONFIG_LITEX_SOC_CONTROLLER) += litex/
+obj-y				+= loongson/
 obj-y				+= mediatek/
 obj-y				+= microchip/
 obj-y				+= pxa/
diff --git a/drivers/soc/loongson/Kconfig b/drivers/soc/loongson/Kconfig
new file mode 100644
index 000000000000..df52599ae87b
--- /dev/null
+++ b/drivers/soc/loongson/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Loongson-2 series SoC drivers
+#
+
+config LOONGSON2_GUTS
+	tristate "Loongson-2 SoC Global UtiliTieS (GUTS) register block"
+	depends on LOONGARCH || COMPILE_TEST
+	select SOC_BUS
+	help
+	  The global utilities block controls PCIE device enabling, alternate
+	  function selection for multiplexed signals, consistency of HDA, USB
+	  and PCIE, configuration of memory controller, rtc controller, lio
+	  controller, and clock control. This patch adds a driver to manage
+	  and access global utilities block for loongarch architecture Loongson-2
+	  SoCs. Initially only reading SVR and registering soc device are
+	  supported. Other guts accesses, such as reading PMON configuration by
+	  default, should eventually be added into this driver as well.
diff --git a/drivers/soc/loongson/Makefile b/drivers/soc/loongson/Makefile
new file mode 100644
index 000000000000..263c486df638
--- /dev/null
+++ b/drivers/soc/loongson/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Makefile for the Linux Kernel SoC Loongson-2 specific device drivers
+#
+
+obj-$(CONFIG_LOONGSON2_GUTS)		+= loongson2_guts.o
diff --git a/drivers/soc/loongson/loongson2_guts.c b/drivers/soc/loongson/loongson2_guts.c
new file mode 100644
index 000000000000..8f3d5465c7e8
--- /dev/null
+++ b/drivers/soc/loongson/loongson2_guts.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Author: Yinbo Zhu <zhuyinbo@loongson.cn>
+ * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/sys_soc.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+static struct soc_device_attribute soc_dev_attr;
+static struct soc_device *soc_dev;
+
+/*
+ * Global Utility Registers.
+ *
+ * Not all registers defined in this structure are available on all chips, so
+ * you are expected to know whether a given register actually exists on your
+ * chip before you access it.
+ *
+ * Also, some registers are similar on different chips but have slightly
+ * different names.  In these cases, one name is chosen to avoid extraneous
+ * #ifdefs.
+ */
+struct scfg_guts {
+	u32     svr;            /* Version Register */
+	u8      res0[4];
+	u16     feature;        /* Feature Register */
+	u32     vendor;         /* Vendor Register */
+	u8      res1[6];
+	u32     id;
+	u8      res2[0x3ff8 - 0x18];
+	u32     chip;
+};
+
+static struct guts {
+	struct scfg_guts __iomem *regs;
+	bool little_endian;
+} *guts;
+
+struct loongson2_soc_die_attr {
+	char	*die;
+	u32	svr;
+	u32	mask;
+};
+
+/* SoC die attribute definition for Loongson-2 platform */
+static const struct loongson2_soc_die_attr loongson2_soc_die[] = {
+
+	/*
+	 * LA-based SoCs Loongson-2 Series
+	 */
+
+	/* Die: 2k1000la, SoC: 2k1000la */
+	{ .die		= "2K1000LA",
+	  .svr		= 0x00000013,
+	  .mask		= 0x000000ff,
+	},
+	{ },
+};
+
+static const struct loongson2_soc_die_attr *loongson2_soc_die_match(
+	u32 svr, const struct loongson2_soc_die_attr *matches)
+{
+	while (matches->svr) {
+		if (matches->svr == (svr & matches->mask))
+			return matches;
+		matches++;
+	};
+
+	return NULL;
+}
+
+static u32 loongson2_guts_get_svr(void)
+{
+	u32 svr = 0;
+
+	if (!guts || !guts->regs)
+		return svr;
+
+	if (guts->little_endian)
+		svr = ioread32(&guts->regs->svr);
+	else
+		svr = ioread32be(&guts->regs->svr);
+
+	return svr;
+}
+
+static int loongson2_guts_probe(struct platform_device *pdev)
+{
+	struct device_node *root, *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	const struct loongson2_soc_die_attr *soc_die;
+	const char *machine;
+	u32 svr;
+
+	/* Initialize guts */
+	guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
+	if (!guts)
+		return -ENOMEM;
+
+	guts->little_endian = of_property_read_bool(np, "little-endian");
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	guts->regs = ioremap(res->start, res->end - res->start + 1);
+	if (IS_ERR(guts->regs))
+		return PTR_ERR(guts->regs);
+
+	/* Register soc device */
+	root = of_find_node_by_path("/");
+	if (of_property_read_string(root, "model", &machine))
+		of_property_read_string_index(root, "compatible", 0, &machine);
+	of_node_put(root);
+	if (machine)
+		soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+
+	svr = loongson2_guts_get_svr();
+	soc_die = loongson2_soc_die_match(svr, loongson2_soc_die);
+	if (soc_die) {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL,
+						     "Loongson %s", soc_die->die);
+	} else {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "Loongson");
+	}
+	if (!soc_dev_attr.family)
+		return -ENOMEM;
+	soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL,
+					     "svr:0x%08x", svr);
+	if (!soc_dev_attr.soc_id)
+		return -ENOMEM;
+	soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
+					       (svr >>  4) & 0xf, svr & 0xf);
+	if (!soc_dev_attr.revision)
+		return -ENOMEM;
+
+	soc_dev = soc_device_register(&soc_dev_attr);
+	if (IS_ERR(soc_dev))
+		return PTR_ERR(soc_dev);
+
+	pr_info("Machine: %s\n", soc_dev_attr.machine);
+	pr_info("SoC family: %s\n", soc_dev_attr.family);
+	pr_info("SoC ID: %s, Revision: %s\n",
+		soc_dev_attr.soc_id, soc_dev_attr.revision);
+
+	return 0;
+}
+
+static int loongson2_guts_remove(struct platform_device *dev)
+{
+	soc_device_unregister(soc_dev);
+
+	return 0;
+}
+
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for Loongson-2 SoCs.
+ */
+static const struct of_device_id loongson2_guts_of_match[] = {
+	{ .compatible = "loongson,ls2k-chipid", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, loongson2_guts_of_match);
+
+static struct platform_driver loongson2_guts_driver = {
+	.driver = {
+		.name = "loongson2-guts",
+		.of_match_table = loongson2_guts_of_match,
+	},
+	.probe = loongson2_guts_probe,
+	.remove = loongson2_guts_remove,
+};
+
+static int __init loongson2_guts_init(void)
+{
+	return platform_driver_register(&loongson2_guts_driver);
+}
+core_initcall(loongson2_guts_init);
+
+static void __exit loongson2_guts_exit(void)
+{
+	platform_driver_unregister(&loongson2_guts_driver);
+}
+module_exit(loongson2_guts_exit);
-- 
2.20.1


^ permalink raw reply related	[relevance 5%]

* [PATCH v2] MAINTAINERS: Add drivers/firmware/google/ entry
@ 2023-07-24  8:12  6% Tzung-Bi Shih
  0 siblings, 0 replies; 200+ results
From: Tzung-Bi Shih @ 2023-07-24  8:12 UTC (permalink / raw)
  To: bleung, groeck
  Cc: gregkh, chrome-platform, tzungbi, jwerner, swboyd, briannorris,
	dianders, sjg, dossym

From: Brian Norris <briannorris@chromium.org>

These are mostly used for Chrome platforms, so group it in with the same
mailing list, repo, and (one) committer.

Signed-off-by: Brian Norris <briannorris@chromium.org>
Acked-by: Julius Werner <jwerner@chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
---
This is a revival for v1[1] as it is few-months-old.

Planning to let chrome-platform-firmware use:
- "for-firmware-kernelci" branch for KernelCI[2].
- "for-firmware-next" branch for both 0-day[3] and linux-next.  Patches can
  rebase onto the branch if they are aiming to chrome-platform-firmware.

Haven't figured out how to make it in linux-next specific files though
(e.g. [4]).

[1]: https://patchwork.kernel.org/project/chrome-platform/patch/20221021172624.1.I119456791d197eb7d159f09e7479d8759008a954@changeid/
[2]: https://github.com/kernelci/kernelci-core/pull/2028
[3]: https://github.com/intel/lkp-tests/pull/312
[4]: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=4d2c646ac07cf4a35ef1c4a935a1a4fd6c6b1a36

Changes from v1:
- Update Tzung-Bi's email address.

 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3be1bdfe8ecc..8293a4ab82d8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8758,6 +8758,15 @@ S:	Supported
 F:	Documentation/networking/device_drivers/ethernet/google/gve.rst
 F:	drivers/net/ethernet/google
 
+GOOGLE FIRMWARE DRIVERS
+M:	Tzung-Bi Shih <tzungbi@kernel.org>
+R:	Brian Norris <briannorris@chromium.org>
+R:	Julius Werner <jwerner@chromium.org>
+L:	chrome-platform@lists.linux.dev
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git
+F:	drivers/firmware/google/
+
 GPD POCKET FAN DRIVER
 M:	Hans de Goede <hdegoede@redhat.com>
 L:	platform-driver-x86@vger.kernel.org
-- 
2.41.0.487.g6d72f3e995-goog


^ permalink raw reply related	[relevance 6%]

* [PATCH 3/9] mm/damon/dbgfs: implement deprecation notice file
    2024-01-30  1:35  6% ` [PATCH 2/9] mm/damon: rename CONFIG_DAMON_DBGFS to DAMON_DBGFS_DEPRECATED SeongJae Park
@ 2024-01-30  1:35  6% ` SeongJae Park
  1 sibling, 0 replies; 200+ results
From: SeongJae Park @ 2024-01-30  1:35 UTC (permalink / raw)
  To: Andrew Morton; +Cc: SeongJae Park, damon, linux-mm, linux-kernel

Implement a read-only file for DAMON debugfs interface deprecation
notice, to let users who manually read/write the DAMON debugfs files
from their shell command line easily notice the fact.

Signed-off-by: SeongJae Park <sj@kernel.org>
---
 mm/damon/dbgfs.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c
index 7dac24e69e3b..fc6ece5a9f37 100644
--- a/mm/damon/dbgfs.c
+++ b/mm/damon/dbgfs.c
@@ -805,6 +805,18 @@ static void dbgfs_destroy_ctx(struct damon_ctx *ctx)
 	damon_destroy_ctx(ctx);
 }
 
+static ssize_t damon_dbgfs_deprecated_read(struct file *file,
+		char __user *buf, size_t count, loff_t *ppos)
+{
+	char kbuf[512] = "DAMON debugfs interface is deprecated, "
+		     "so users should move to DAMON_SYSFS. If you cannot, "
+		     "please report your usecase to damon@lists.linux.dev and "
+		     "linux-mm@kvack.org.\n";
+	int len = strnlen(kbuf, 1024);
+
+	return simple_read_from_buffer(buf, count, ppos, kbuf, len);
+}
+
 /*
  * Make a context of @name and create a debugfs directory for it.
  *
@@ -1056,6 +1068,10 @@ static int damon_dbgfs_static_file_open(struct inode *inode, struct file *file)
 	return nonseekable_open(inode, file);
 }
 
+static const struct file_operations deprecated_fops = {
+	.read = damon_dbgfs_deprecated_read,
+};
+
 static const struct file_operations mk_contexts_fops = {
 	.open = damon_dbgfs_static_file_open,
 	.write = dbgfs_mk_context_write,
@@ -1076,9 +1092,9 @@ static int __init __damon_dbgfs_init(void)
 {
 	struct dentry *dbgfs_root;
 	const char * const file_names[] = {"mk_contexts", "rm_contexts",
-		"monitor_on"};
+		"monitor_on", "DEPRECATED"};
 	const struct file_operations *fops[] = {&mk_contexts_fops,
-		&rm_contexts_fops, &monitor_on_fops};
+		&rm_contexts_fops, &monitor_on_fops, &deprecated_fops};
 	int i;
 
 	dbgfs_root = debugfs_create_dir("damon", NULL);
-- 
2.39.2


^ permalink raw reply related	[relevance 6%]

* [PATCH 5.13 755/800] powerpc/papr_scm: Make perf_stats invisible if perf-stats unavailable
  @ 2021-07-12  6:12  6% ` Greg Kroah-Hartman
  0 siblings, 0 replies; 200+ results
From: Greg Kroah-Hartman @ 2021-07-12  6:12 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, stable, Vaibhav Jain, Dan Williams,
	Michael Ellerman, Sasha Levin

From: Vaibhav Jain <vaibhav@linux.ibm.com>

[ Upstream commit ed78f56e1271f108e8af61baeba383dcd77adbec ]

In case performance stats for an nvdimm are not available, reading the
'perf_stats' sysfs file returns an -ENOENT error. A better approach is
to make the 'perf_stats' file entirely invisible to indicate that
performance stats for an nvdimm are unavailable.

So this patch updates 'papr_nd_attribute_group' to add a 'is_visible'
callback implemented as newly introduced 'papr_nd_attribute_visible()'
that returns an appropriate mode in case performance stats aren't
supported in a given nvdimm.

Also the initialization of 'papr_scm_priv.stat_buffer_len' is moved
from papr_scm_nvdimm_init() to papr_scm_probe() so that it value is
available when 'papr_nd_attribute_visible()' is called during nvdimm
initialization.

Even though 'perf_stats' attribute is available since v5.9, there are
no known user-space tools/scripts that are dependent on presence of its
sysfs file. Hence I dont expect any user-space breakage with this
patch.

Fixes: 2d02bf835e57 ("powerpc/papr_scm: Fetch nvdimm performance stats from PHYP")
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210513092349.285021-1-vaibhav@linux.ibm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 Documentation/ABI/testing/sysfs-bus-papr-pmem |  8 +++--
 arch/powerpc/platforms/pseries/papr_scm.c     | 35 +++++++++++++------
 2 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem
index 92e2db0e2d3d..95254cec92bf 100644
--- a/Documentation/ABI/testing/sysfs-bus-papr-pmem
+++ b/Documentation/ABI/testing/sysfs-bus-papr-pmem
@@ -39,9 +39,11 @@ KernelVersion:	v5.9
 Contact:	linuxppc-dev <linuxppc-dev@lists.ozlabs.org>, nvdimm@lists.linux.dev,
 Description:
 		(RO) Report various performance stats related to papr-scm NVDIMM
-		device.  Each stat is reported on a new line with each line
-		composed of a stat-identifier followed by it value. Below are
-		currently known dimm performance stats which are reported:
+		device. This attribute is only available for NVDIMM devices
+		that support reporting NVDIMM performance stats. Each stat is
+		reported on a new line with each line composed of a
+		stat-identifier followed by it value. Below are currently known
+		dimm performance stats which are reported:
 
 		* "CtlResCt" : Controller Reset Count
 		* "CtlResTm" : Controller Reset Elapsed Time
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index 8335e13836db..d34e6eb4be0d 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -901,6 +901,20 @@ static ssize_t flags_show(struct device *dev,
 }
 DEVICE_ATTR_RO(flags);
 
+static umode_t papr_nd_attribute_visible(struct kobject *kobj,
+					 struct attribute *attr, int n)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct nvdimm *nvdimm = to_nvdimm(dev);
+	struct papr_scm_priv *p = nvdimm_provider_data(nvdimm);
+
+	/* For if perf-stats not available remove perf_stats sysfs */
+	if (attr == &dev_attr_perf_stats.attr && p->stat_buffer_len == 0)
+		return 0;
+
+	return attr->mode;
+}
+
 /* papr_scm specific dimm attributes */
 static struct attribute *papr_nd_attributes[] = {
 	&dev_attr_flags.attr,
@@ -910,6 +924,7 @@ static struct attribute *papr_nd_attributes[] = {
 
 static struct attribute_group papr_nd_attribute_group = {
 	.name = "papr",
+	.is_visible = papr_nd_attribute_visible,
 	.attrs = papr_nd_attributes,
 };
 
@@ -925,7 +940,6 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
 	struct nd_region_desc ndr_desc;
 	unsigned long dimm_flags;
 	int target_nid, online_nid;
-	ssize_t stat_size;
 
 	p->bus_desc.ndctl = papr_scm_ndctl;
 	p->bus_desc.module = THIS_MODULE;
@@ -1010,16 +1024,6 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
 	list_add_tail(&p->region_list, &papr_nd_regions);
 	mutex_unlock(&papr_ndr_lock);
 
-	/* Try retriving the stat buffer and see if its supported */
-	stat_size = drc_pmem_query_stats(p, NULL, 0);
-	if (stat_size > 0) {
-		p->stat_buffer_len = stat_size;
-		dev_dbg(&p->pdev->dev, "Max perf-stat size %lu-bytes\n",
-			p->stat_buffer_len);
-	} else {
-		dev_info(&p->pdev->dev, "Dimm performance stats unavailable\n");
-	}
-
 	return 0;
 
 err:	nvdimm_bus_unregister(p->bus);
@@ -1097,6 +1101,7 @@ static int papr_scm_probe(struct platform_device *pdev)
 	struct papr_scm_priv *p;
 	u8 uuid_raw[UUID_SIZE];
 	const char *uuid_str;
+	ssize_t stat_size;
 	uuid_t uuid;
 	int rc;
 
@@ -1181,6 +1186,14 @@ static int papr_scm_probe(struct platform_device *pdev)
 	p->res.name  = pdev->name;
 	p->res.flags = IORESOURCE_MEM;
 
+	/* Try retrieving the stat buffer and see if its supported */
+	stat_size = drc_pmem_query_stats(p, NULL, 0);
+	if (stat_size > 0) {
+		p->stat_buffer_len = stat_size;
+		dev_dbg(&p->pdev->dev, "Max perf-stat size %lu-bytes\n",
+			p->stat_buffer_len);
+	}
+
 	rc = papr_scm_nvdimm_init(p);
 	if (rc)
 		goto err2;
-- 
2.30.2




^ permalink raw reply related	[relevance 6%]

* [PATCH v5 1/2] soc: loongson: add GUTS driver for loongson-2 platforms
@ 2022-11-03  8:19  6% Yinbo Zhu
  2022-11-03  8:19  5% ` [PATCH v5 2/2] dt-bindings: soc: add loongson-2 chipid Yinbo Zhu
  0 siblings, 1 reply; 200+ results
From: Yinbo Zhu @ 2022-11-03  8:19 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, Yinbo Zhu

The global utilities block controls PCIE device enabling, alternate
function selection for multiplexed signals, consistency of HDA, USB
and PCIE, configuration of memory controller, rtc controller, lio
controller, and clock control.

This patch adds a driver to manage and access global utilities block
for loongarch architecture Loongson-2 SoCs. Initially only reading SVR
and registering soc device are supported. Other guts accesses, such
as reading PMON configuration by default, should eventually be added
into this driver as well.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
---
Change in v5:
		1. Add all history change log information.
Change in v4:
		1. Remove menu information in Kconfig.
Change in v3:
		1. Replace string loongson2/Loongson2 with Loongson-2/loongson-2
	           in commit message, Kconfig, Makefile file.
		2. Replace string LOONGSON2 with LOONGSON-2.
Change in v2:
		1. Add architecture support commit log description.
		2. Add other guts accesses plan commit log description.
		3. Add "depends on LOONGARCH || COMPILE_TEST" for
		   LOONGSON2_GUTS in Kconfig.
		4. Move the scfg_guts to .c file from .h and delete .h.
		5. Remove __packed on scfg_guts.

 MAINTAINERS                           |   6 +
 drivers/soc/Kconfig                   |   1 +
 drivers/soc/Makefile                  |   1 +
 drivers/soc/loongson/Kconfig          |  18 +++
 drivers/soc/loongson/Makefile         |   6 +
 drivers/soc/loongson/loongson2_guts.c | 189 ++++++++++++++++++++++++++
 6 files changed, 221 insertions(+)
 create mode 100644 drivers/soc/loongson/Kconfig
 create mode 100644 drivers/soc/loongson/Makefile
 create mode 100644 drivers/soc/loongson/loongson2_guts.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c9dc5ddbd9fe..20ce056ae207 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12041,6 +12041,12 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
 F:	drivers/pinctrl/pinctrl-loongson2.c
 
+LOONGSON-2 SOC SERIES GUTS DRIVER
+M:	Yinbo Zhu <zhuyinbo@loongson.cn>
+L:	loongarch@lists.linux.dev
+S:	Maintained
+F:	drivers/soc/loongson/loongson2_guts.c
+
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
 M:	Sathya Prakash <sathya.prakash@broadcom.com>
 M:	Sreekanth Reddy <sreekanth.reddy@broadcom.com>
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index e461c071189b..5dbb09f843f7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -13,6 +13,7 @@ source "drivers/soc/fujitsu/Kconfig"
 source "drivers/soc/imx/Kconfig"
 source "drivers/soc/ixp4xx/Kconfig"
 source "drivers/soc/litex/Kconfig"
+source "drivers/soc/loongson/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/microchip/Kconfig"
 source "drivers/soc/pxa/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 69ba6508cf2c..fff513bd522d 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -18,6 +18,7 @@ obj-y				+= imx/
 obj-y				+= ixp4xx/
 obj-$(CONFIG_SOC_XWAY)		+= lantiq/
 obj-$(CONFIG_LITEX_SOC_CONTROLLER) += litex/
+obj-y				+= loongson/
 obj-y				+= mediatek/
 obj-y				+= microchip/
 obj-y				+= pxa/
diff --git a/drivers/soc/loongson/Kconfig b/drivers/soc/loongson/Kconfig
new file mode 100644
index 000000000000..c60119b9d247
--- /dev/null
+++ b/drivers/soc/loongson/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Loongson-2 series SoC drivers
+#
+
+config LOONGSON2_GUTS
+	tristate "Loongson-2 GUTS"
+	depends on LOONGARCH || COMPILE_TEST
+	select SOC_BUS
+	help
+	  The global utilities block controls PCIE device enabling, alternate
+	  function selection for multiplexed signals, consistency of HDA, USB
+	  and PCIE, configuration of memory controller, rtc controller, lio
+	  controller, and clock control. This patch adds a driver to manage
+	  and access global utilities block for loongarch architecture Loongson-2
+	  SoCs. Initially only reading SVR and registering soc device are
+	  supported. Other guts accesses, such as reading PMON configuration by
+	  default, should eventually be added into this driver as well.
diff --git a/drivers/soc/loongson/Makefile b/drivers/soc/loongson/Makefile
new file mode 100644
index 000000000000..263c486df638
--- /dev/null
+++ b/drivers/soc/loongson/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Makefile for the Linux Kernel SoC Loongson-2 specific device drivers
+#
+
+obj-$(CONFIG_LOONGSON2_GUTS)		+= loongson2_guts.o
diff --git a/drivers/soc/loongson/loongson2_guts.c b/drivers/soc/loongson/loongson2_guts.c
new file mode 100644
index 000000000000..8f3d5465c7e8
--- /dev/null
+++ b/drivers/soc/loongson/loongson2_guts.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Author: Yinbo Zhu <zhuyinbo@loongson.cn>
+ * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/sys_soc.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+static struct soc_device_attribute soc_dev_attr;
+static struct soc_device *soc_dev;
+
+/*
+ * Global Utility Registers.
+ *
+ * Not all registers defined in this structure are available on all chips, so
+ * you are expected to know whether a given register actually exists on your
+ * chip before you access it.
+ *
+ * Also, some registers are similar on different chips but have slightly
+ * different names.  In these cases, one name is chosen to avoid extraneous
+ * #ifdefs.
+ */
+struct scfg_guts {
+	u32     svr;            /* Version Register */
+	u8      res0[4];
+	u16     feature;        /* Feature Register */
+	u32     vendor;         /* Vendor Register */
+	u8      res1[6];
+	u32     id;
+	u8      res2[0x3ff8 - 0x18];
+	u32     chip;
+};
+
+static struct guts {
+	struct scfg_guts __iomem *regs;
+	bool little_endian;
+} *guts;
+
+struct loongson2_soc_die_attr {
+	char	*die;
+	u32	svr;
+	u32	mask;
+};
+
+/* SoC die attribute definition for Loongson-2 platform */
+static const struct loongson2_soc_die_attr loongson2_soc_die[] = {
+
+	/*
+	 * LA-based SoCs Loongson-2 Series
+	 */
+
+	/* Die: 2k1000la, SoC: 2k1000la */
+	{ .die		= "2K1000LA",
+	  .svr		= 0x00000013,
+	  .mask		= 0x000000ff,
+	},
+	{ },
+};
+
+static const struct loongson2_soc_die_attr *loongson2_soc_die_match(
+	u32 svr, const struct loongson2_soc_die_attr *matches)
+{
+	while (matches->svr) {
+		if (matches->svr == (svr & matches->mask))
+			return matches;
+		matches++;
+	};
+
+	return NULL;
+}
+
+static u32 loongson2_guts_get_svr(void)
+{
+	u32 svr = 0;
+
+	if (!guts || !guts->regs)
+		return svr;
+
+	if (guts->little_endian)
+		svr = ioread32(&guts->regs->svr);
+	else
+		svr = ioread32be(&guts->regs->svr);
+
+	return svr;
+}
+
+static int loongson2_guts_probe(struct platform_device *pdev)
+{
+	struct device_node *root, *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	const struct loongson2_soc_die_attr *soc_die;
+	const char *machine;
+	u32 svr;
+
+	/* Initialize guts */
+	guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
+	if (!guts)
+		return -ENOMEM;
+
+	guts->little_endian = of_property_read_bool(np, "little-endian");
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	guts->regs = ioremap(res->start, res->end - res->start + 1);
+	if (IS_ERR(guts->regs))
+		return PTR_ERR(guts->regs);
+
+	/* Register soc device */
+	root = of_find_node_by_path("/");
+	if (of_property_read_string(root, "model", &machine))
+		of_property_read_string_index(root, "compatible", 0, &machine);
+	of_node_put(root);
+	if (machine)
+		soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+
+	svr = loongson2_guts_get_svr();
+	soc_die = loongson2_soc_die_match(svr, loongson2_soc_die);
+	if (soc_die) {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL,
+						     "Loongson %s", soc_die->die);
+	} else {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "Loongson");
+	}
+	if (!soc_dev_attr.family)
+		return -ENOMEM;
+	soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL,
+					     "svr:0x%08x", svr);
+	if (!soc_dev_attr.soc_id)
+		return -ENOMEM;
+	soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
+					       (svr >>  4) & 0xf, svr & 0xf);
+	if (!soc_dev_attr.revision)
+		return -ENOMEM;
+
+	soc_dev = soc_device_register(&soc_dev_attr);
+	if (IS_ERR(soc_dev))
+		return PTR_ERR(soc_dev);
+
+	pr_info("Machine: %s\n", soc_dev_attr.machine);
+	pr_info("SoC family: %s\n", soc_dev_attr.family);
+	pr_info("SoC ID: %s, Revision: %s\n",
+		soc_dev_attr.soc_id, soc_dev_attr.revision);
+
+	return 0;
+}
+
+static int loongson2_guts_remove(struct platform_device *dev)
+{
+	soc_device_unregister(soc_dev);
+
+	return 0;
+}
+
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for Loongson-2 SoCs.
+ */
+static const struct of_device_id loongson2_guts_of_match[] = {
+	{ .compatible = "loongson,ls2k-chipid", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, loongson2_guts_of_match);
+
+static struct platform_driver loongson2_guts_driver = {
+	.driver = {
+		.name = "loongson2-guts",
+		.of_match_table = loongson2_guts_of_match,
+	},
+	.probe = loongson2_guts_probe,
+	.remove = loongson2_guts_remove,
+};
+
+static int __init loongson2_guts_init(void)
+{
+	return platform_driver_register(&loongson2_guts_driver);
+}
+core_initcall(loongson2_guts_init);
+
+static void __exit loongson2_guts_exit(void)
+{
+	platform_driver_unregister(&loongson2_guts_driver);
+}
+module_exit(loongson2_guts_exit);
-- 
2.20.1


^ permalink raw reply related	[relevance 6%]

* [PATCH v2 1/2] soc: loongson: add GUTS driver for loongson2 platforms
@ 2022-10-25  3:51  6% Yinbo Zhu
  2022-10-25  3:51  5% ` [PATCH v2 2/2] dt-bindings: soc: add loongson2 guts Yinbo Zhu
  0 siblings, 1 reply; 200+ results
From: Yinbo Zhu @ 2022-10-25  3:51 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, Yinbo Zhu

The global utilities block controls PCIE device enabling, alternate
function selection for multiplexed signals, consistency of HDA, USB
and PCIE, configuration of memory controller, rtc controller, lio
controller, and clock control.

This patch adds a driver to manage and access global utilities block
for loongarch architecture loongson2 SoCs. Initially only reading SVR
and registering soc device are supported. Other guts accesses, such
as reading PMON configuration by default, should eventually be added
into this driver as well.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
---
Change in v2:
		1. Add architecture support commit log description.
		2. Add other guts accesses plan commit log description.
		3. Add "depends on LOONGARCH || COMPILE_TEST" for
		   LOONGSON2_GUTS in Kconfig.
		4. Move the scfg_guts to .c file from .h and delete .h.
		5. Remove __packed on scfg_guts.

 MAINTAINERS                           |   6 +
 drivers/soc/Kconfig                   |   1 +
 drivers/soc/Makefile                  |   1 +
 drivers/soc/loongson/Kconfig          |  20 +++
 drivers/soc/loongson/Makefile         |   6 +
 drivers/soc/loongson/loongson2_guts.c | 189 ++++++++++++++++++++++++++
 6 files changed, 223 insertions(+)
 create mode 100644 drivers/soc/loongson/Kconfig
 create mode 100644 drivers/soc/loongson/Makefile
 create mode 100644 drivers/soc/loongson/loongson2_guts.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 2d002509fc65..0f06dc83f7c6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11930,6 +11930,12 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
 F:	drivers/pinctrl/pinctrl-loongson2.c
 
+LOONGSON2 SOC SERIES GUTS DRIVER
+M:	Yinbo Zhu <zhuyinbo@loongson.cn>
+L:	loongarch@lists.linux.dev
+S:	Maintained
+F:	drivers/soc/loongson/loongson2_guts.c
+
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
 M:	Sathya Prakash <sathya.prakash@broadcom.com>
 M:	Sreekanth Reddy <sreekanth.reddy@broadcom.com>
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index e461c071189b..5dbb09f843f7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -13,6 +13,7 @@ source "drivers/soc/fujitsu/Kconfig"
 source "drivers/soc/imx/Kconfig"
 source "drivers/soc/ixp4xx/Kconfig"
 source "drivers/soc/litex/Kconfig"
+source "drivers/soc/loongson/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/microchip/Kconfig"
 source "drivers/soc/pxa/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 69ba6508cf2c..fff513bd522d 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -18,6 +18,7 @@ obj-y				+= imx/
 obj-y				+= ixp4xx/
 obj-$(CONFIG_SOC_XWAY)		+= lantiq/
 obj-$(CONFIG_LITEX_SOC_CONTROLLER) += litex/
+obj-y				+= loongson/
 obj-y				+= mediatek/
 obj-y				+= microchip/
 obj-y				+= pxa/
diff --git a/drivers/soc/loongson/Kconfig b/drivers/soc/loongson/Kconfig
new file mode 100644
index 000000000000..04a4dd5192ef
--- /dev/null
+++ b/drivers/soc/loongson/Kconfig
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Loongson2 series SoC drivers
+#
+
+menu "Loongson2 series SoC drivers"
+
+config LOONGSON2_GUTS
+	tristate "LOONGSON2 GUTS"
+	depends on LOONGARCH || COMPILE_TEST
+	select SOC_BUS
+	help
+	  The global utilities block controls PCIE device enabling, alternate
+	  function selection for multiplexed signals, consistency of HDA, USB
+	  and PCIE, configuration of memory controller, rtc controller, lio
+	  controller, and clock control. This patch adds a driver to manage
+	  and access global utilities block for loongarch architecture loongson2
+	  SoCs. Initially only reading SVR and registering soc device are
+	  supported. Other guts accesses, such as reading PMON configuration by
+	  default, should eventually be added into this driver as well.
diff --git a/drivers/soc/loongson/Makefile b/drivers/soc/loongson/Makefile
new file mode 100644
index 000000000000..acfc90a624c9
--- /dev/null
+++ b/drivers/soc/loongson/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Makefile for the Linux Kernel SoC loongson2 specific device drivers
+#
+
+obj-$(CONFIG_LOONGSON2_GUTS)		+= loongson2_guts.o
diff --git a/drivers/soc/loongson/loongson2_guts.c b/drivers/soc/loongson/loongson2_guts.c
new file mode 100644
index 000000000000..15db9ebc3f14
--- /dev/null
+++ b/drivers/soc/loongson/loongson2_guts.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Author: Yinbo Zhu <zhuyinbo@loongson.cn>
+ * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/sys_soc.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+static struct soc_device_attribute soc_dev_attr;
+static struct soc_device *soc_dev;
+
+/*
+ * Global Utility Registers.
+ *
+ * Not all registers defined in this structure are available on all chips, so
+ * you are expected to know whether a given register actually exists on your
+ * chip before you access it.
+ *
+ * Also, some registers are similar on different chips but have slightly
+ * different names.  In these cases, one name is chosen to avoid extraneous
+ * #ifdefs.
+ */
+struct scfg_guts {
+	u32     svr;            /* Version Register */
+	u8      res0[4];
+	u16     feature;        /* Feature Register */
+	u32     vendor;         /* Vendor Register */
+	u8      res1[6];
+	u32     id;
+	u8      res2[0x3ff8 - 0x18];
+	u32     chip;
+};
+
+static struct guts {
+	struct scfg_guts __iomem *regs;
+	bool little_endian;
+} *guts;
+
+struct loongson2_soc_die_attr {
+	char	*die;
+	u32	svr;
+	u32	mask;
+};
+
+/* SoC die attribute definition for loongson2 platform */
+static const struct loongson2_soc_die_attr loongson2_soc_die[] = {
+
+	/*
+	 * LA-based SoCs Loongson2 Series
+	 */
+
+	/* Die: 2k1000la, SoC: 2k1000la */
+	{ .die		= "2K1000LA",
+	  .svr		= 0x00000013,
+	  .mask		= 0x000000ff,
+	},
+	{ },
+};
+
+static const struct loongson2_soc_die_attr *loongson2_soc_die_match(
+	u32 svr, const struct loongson2_soc_die_attr *matches)
+{
+	while (matches->svr) {
+		if (matches->svr == (svr & matches->mask))
+			return matches;
+		matches++;
+	};
+
+	return NULL;
+}
+
+static u32 loongson2_guts_get_svr(void)
+{
+	u32 svr = 0;
+
+	if (!guts || !guts->regs)
+		return svr;
+
+	if (guts->little_endian)
+		svr = ioread32(&guts->regs->svr);
+	else
+		svr = ioread32be(&guts->regs->svr);
+
+	return svr;
+}
+
+static int loongson2_guts_probe(struct platform_device *pdev)
+{
+	struct device_node *root, *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	const struct loongson2_soc_die_attr *soc_die;
+	const char *machine;
+	u32 svr;
+
+	/* Initialize guts */
+	guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
+	if (!guts)
+		return -ENOMEM;
+
+	guts->little_endian = of_property_read_bool(np, "little-endian");
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	guts->regs = ioremap(res->start, res->end - res->start + 1);
+	if (IS_ERR(guts->regs))
+		return PTR_ERR(guts->regs);
+
+	/* Register soc device */
+	root = of_find_node_by_path("/");
+	if (of_property_read_string(root, "model", &machine))
+		of_property_read_string_index(root, "compatible", 0, &machine);
+	of_node_put(root);
+	if (machine)
+		soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+
+	svr = loongson2_guts_get_svr();
+	soc_die = loongson2_soc_die_match(svr, loongson2_soc_die);
+	if (soc_die) {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL,
+						     "Loongson %s", soc_die->die);
+	} else {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "Loongson");
+	}
+	if (!soc_dev_attr.family)
+		return -ENOMEM;
+	soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL,
+					     "svr:0x%08x", svr);
+	if (!soc_dev_attr.soc_id)
+		return -ENOMEM;
+	soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
+					       (svr >>  4) & 0xf, svr & 0xf);
+	if (!soc_dev_attr.revision)
+		return -ENOMEM;
+
+	soc_dev = soc_device_register(&soc_dev_attr);
+	if (IS_ERR(soc_dev))
+		return PTR_ERR(soc_dev);
+
+	pr_info("Machine: %s\n", soc_dev_attr.machine);
+	pr_info("SoC family: %s\n", soc_dev_attr.family);
+	pr_info("SoC ID: %s, Revision: %s\n",
+		soc_dev_attr.soc_id, soc_dev_attr.revision);
+
+	return 0;
+}
+
+static int loongson2_guts_remove(struct platform_device *dev)
+{
+	soc_device_unregister(soc_dev);
+
+	return 0;
+}
+
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for Loongson2 SoCs.
+ */
+static const struct of_device_id loongson2_guts_of_match[] = {
+	{ .compatible = "loongson,ls2k-guts", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, loongson2_guts_of_match);
+
+static struct platform_driver loongson2_guts_driver = {
+	.driver = {
+		.name = "loongson2-guts",
+		.of_match_table = loongson2_guts_of_match,
+	},
+	.probe = loongson2_guts_probe,
+	.remove = loongson2_guts_remove,
+};
+
+static int __init loongson2_guts_init(void)
+{
+	return platform_driver_register(&loongson2_guts_driver);
+}
+core_initcall(loongson2_guts_init);
+
+static void __exit loongson2_guts_exit(void)
+{
+	platform_driver_unregister(&loongson2_guts_driver);
+}
+module_exit(loongson2_guts_exit);
-- 
2.31.1


^ permalink raw reply related	[relevance 6%]

* [tip: x86/urgent] MAINTAINERS: Add Intel TDX entry
@ 2023-11-03 21:26  6% tip-bot2 for Kirill A. Shutemov
  0 siblings, 0 replies; 200+ results
From: tip-bot2 for Kirill A. Shutemov @ 2023-11-03 21:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Dave Hansen, Kirill A. Shutemov, Kuppuswamy Sathyanarayanan,
	Kai Huang, x86, linux-kernel

The following commit has been merged into the x86/urgent branch of tip:

Commit-ID:     a4b883806ffe5ae5e99459d64d760e205162c729
Gitweb:        https://git.kernel.org/tip/a4b883806ffe5ae5e99459d64d760e205162c729
Author:        Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
AuthorDate:    Thu, 02 Nov 2023 02:33:14 +03:00
Committer:     Dave Hansen <dave.hansen@linux.intel.com>
CommitterDate: Fri, 03 Nov 2023 14:20:37 -07:00

MAINTAINERS: Add Intel TDX entry

Add myself as Intel TDX maintainer.

I drove upstreaming most of TDX code so far and I will continue
working on TDX for foreseeable future.

[ dhansen: * add myself as a reviewer too and change
	   * Swap Maintained=>Supported.  I double
	     checked Kirill is still being paid
	   * add drivers/virt/coco/tdx-guest ]

Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Acked-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Acked-by: Kai Huang <kai.huang@intel.com>
Link: https://lore.kernel.org/all/20231101233314.2567-1-kirill.shutemov%40linux.intel.com
---
 MAINTAINERS | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index dd5de54..b697020 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23460,6 +23460,20 @@ F:	arch/x86/kernel/dumpstack.c
 F:	arch/x86/kernel/stacktrace.c
 F:	arch/x86/kernel/unwind_*.c
 
+X86 TRUST DOMAIN EXTENSIONS (TDX)
+M:	Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+R:	Dave Hansen <dave.hansen@linux.intel.com>
+L:	x86@kernel.org
+L:	linux-coco@lists.linux.dev
+S:	Supported
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/tdx
+F:	arch/x86/boot/compressed/tdx*
+F:	arch/x86/coco/tdx/
+F:	arch/x86/include/asm/shared/tdx.h
+F:	arch/x86/include/asm/tdx.h
+F:	arch/x86/virt/vmx/tdx/
+F:	drivers/virt/coco/tdx-guest
+
 X86 VDSO
 M:	Andy Lutomirski <luto@kernel.org>
 L:	linux-kernel@vger.kernel.org

^ permalink raw reply related	[relevance 6%]

* [PATCH v3 1/2] soc: loongson: add GUTS driver for loongson-2 platforms
@ 2022-10-29  8:21  6% Yinbo Zhu
  2022-10-29  8:21  5% ` [PATCH v3 2/2] dt-bindings: soc: add loongson-2 chipid Yinbo Zhu
  0 siblings, 1 reply; 200+ results
From: Yinbo Zhu @ 2022-10-29  8:21 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, Yinbo Zhu

The global utilities block controls PCIE device enabling, alternate
function selection for multiplexed signals, consistency of HDA, USB
and PCIE, configuration of memory controller, rtc controller, lio
controller, and clock control.

This patch adds a driver to manage and access global utilities block
for loongarch architecture Loongson-2 SoCs. Initially only reading SVR
and registering soc device are supported. Other guts accesses, such
as reading PMON configuration by default, should eventually be added
into this driver as well.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
---
Change in v3:
		1. Replace string loongson2/Loongson2 with Loongson-2/loongson-2
	           in commit message, Kconfig, Makefile file.
		2. Replace string LOONGSON2 with LOONGSON-2.

 MAINTAINERS                           |   6 +
 drivers/soc/Kconfig                   |   1 +
 drivers/soc/Makefile                  |   1 +
 drivers/soc/loongson/Kconfig          |  20 +++
 drivers/soc/loongson/Makefile         |   6 +
 drivers/soc/loongson/loongson2_guts.c | 189 ++++++++++++++++++++++++++
 6 files changed, 223 insertions(+)
 create mode 100644 drivers/soc/loongson/Kconfig
 create mode 100644 drivers/soc/loongson/Makefile
 create mode 100644 drivers/soc/loongson/loongson2_guts.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4fc949c36a44..a02d45dd21ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11930,6 +11930,12 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
 F:	drivers/pinctrl/pinctrl-loongson2.c
 
+LOONGSON-2 SOC SERIES GUTS DRIVER
+M:	Yinbo Zhu <zhuyinbo@loongson.cn>
+L:	loongarch@lists.linux.dev
+S:	Maintained
+F:	drivers/soc/loongson/loongson2_guts.c
+
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
 M:	Sathya Prakash <sathya.prakash@broadcom.com>
 M:	Sreekanth Reddy <sreekanth.reddy@broadcom.com>
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index e461c071189b..5dbb09f843f7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -13,6 +13,7 @@ source "drivers/soc/fujitsu/Kconfig"
 source "drivers/soc/imx/Kconfig"
 source "drivers/soc/ixp4xx/Kconfig"
 source "drivers/soc/litex/Kconfig"
+source "drivers/soc/loongson/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/microchip/Kconfig"
 source "drivers/soc/pxa/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 69ba6508cf2c..fff513bd522d 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -18,6 +18,7 @@ obj-y				+= imx/
 obj-y				+= ixp4xx/
 obj-$(CONFIG_SOC_XWAY)		+= lantiq/
 obj-$(CONFIG_LITEX_SOC_CONTROLLER) += litex/
+obj-y				+= loongson/
 obj-y				+= mediatek/
 obj-y				+= microchip/
 obj-y				+= pxa/
diff --git a/drivers/soc/loongson/Kconfig b/drivers/soc/loongson/Kconfig
new file mode 100644
index 000000000000..64e813962bb0
--- /dev/null
+++ b/drivers/soc/loongson/Kconfig
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Loongson-2 series SoC drivers
+#
+
+menu "Loongson-2 series SoC drivers"
+
+config LOONGSON2_GUTS
+	tristate "Loongson-2 GUTS"
+	depends on LOONGARCH || COMPILE_TEST
+	select SOC_BUS
+	help
+	  The global utilities block controls PCIE device enabling, alternate
+	  function selection for multiplexed signals, consistency of HDA, USB
+	  and PCIE, configuration of memory controller, rtc controller, lio
+	  controller, and clock control. This patch adds a driver to manage
+	  and access global utilities block for loongarch architecture Loongson-2
+	  SoCs. Initially only reading SVR and registering soc device are
+	  supported. Other guts accesses, such as reading PMON configuration by
+	  default, should eventually be added into this driver as well.
diff --git a/drivers/soc/loongson/Makefile b/drivers/soc/loongson/Makefile
new file mode 100644
index 000000000000..263c486df638
--- /dev/null
+++ b/drivers/soc/loongson/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Makefile for the Linux Kernel SoC Loongson-2 specific device drivers
+#
+
+obj-$(CONFIG_LOONGSON2_GUTS)		+= loongson2_guts.o
diff --git a/drivers/soc/loongson/loongson2_guts.c b/drivers/soc/loongson/loongson2_guts.c
new file mode 100644
index 000000000000..8f3d5465c7e8
--- /dev/null
+++ b/drivers/soc/loongson/loongson2_guts.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Author: Yinbo Zhu <zhuyinbo@loongson.cn>
+ * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/sys_soc.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+static struct soc_device_attribute soc_dev_attr;
+static struct soc_device *soc_dev;
+
+/*
+ * Global Utility Registers.
+ *
+ * Not all registers defined in this structure are available on all chips, so
+ * you are expected to know whether a given register actually exists on your
+ * chip before you access it.
+ *
+ * Also, some registers are similar on different chips but have slightly
+ * different names.  In these cases, one name is chosen to avoid extraneous
+ * #ifdefs.
+ */
+struct scfg_guts {
+	u32     svr;            /* Version Register */
+	u8      res0[4];
+	u16     feature;        /* Feature Register */
+	u32     vendor;         /* Vendor Register */
+	u8      res1[6];
+	u32     id;
+	u8      res2[0x3ff8 - 0x18];
+	u32     chip;
+};
+
+static struct guts {
+	struct scfg_guts __iomem *regs;
+	bool little_endian;
+} *guts;
+
+struct loongson2_soc_die_attr {
+	char	*die;
+	u32	svr;
+	u32	mask;
+};
+
+/* SoC die attribute definition for Loongson-2 platform */
+static const struct loongson2_soc_die_attr loongson2_soc_die[] = {
+
+	/*
+	 * LA-based SoCs Loongson-2 Series
+	 */
+
+	/* Die: 2k1000la, SoC: 2k1000la */
+	{ .die		= "2K1000LA",
+	  .svr		= 0x00000013,
+	  .mask		= 0x000000ff,
+	},
+	{ },
+};
+
+static const struct loongson2_soc_die_attr *loongson2_soc_die_match(
+	u32 svr, const struct loongson2_soc_die_attr *matches)
+{
+	while (matches->svr) {
+		if (matches->svr == (svr & matches->mask))
+			return matches;
+		matches++;
+	};
+
+	return NULL;
+}
+
+static u32 loongson2_guts_get_svr(void)
+{
+	u32 svr = 0;
+
+	if (!guts || !guts->regs)
+		return svr;
+
+	if (guts->little_endian)
+		svr = ioread32(&guts->regs->svr);
+	else
+		svr = ioread32be(&guts->regs->svr);
+
+	return svr;
+}
+
+static int loongson2_guts_probe(struct platform_device *pdev)
+{
+	struct device_node *root, *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	const struct loongson2_soc_die_attr *soc_die;
+	const char *machine;
+	u32 svr;
+
+	/* Initialize guts */
+	guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
+	if (!guts)
+		return -ENOMEM;
+
+	guts->little_endian = of_property_read_bool(np, "little-endian");
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	guts->regs = ioremap(res->start, res->end - res->start + 1);
+	if (IS_ERR(guts->regs))
+		return PTR_ERR(guts->regs);
+
+	/* Register soc device */
+	root = of_find_node_by_path("/");
+	if (of_property_read_string(root, "model", &machine))
+		of_property_read_string_index(root, "compatible", 0, &machine);
+	of_node_put(root);
+	if (machine)
+		soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+
+	svr = loongson2_guts_get_svr();
+	soc_die = loongson2_soc_die_match(svr, loongson2_soc_die);
+	if (soc_die) {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL,
+						     "Loongson %s", soc_die->die);
+	} else {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "Loongson");
+	}
+	if (!soc_dev_attr.family)
+		return -ENOMEM;
+	soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL,
+					     "svr:0x%08x", svr);
+	if (!soc_dev_attr.soc_id)
+		return -ENOMEM;
+	soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
+					       (svr >>  4) & 0xf, svr & 0xf);
+	if (!soc_dev_attr.revision)
+		return -ENOMEM;
+
+	soc_dev = soc_device_register(&soc_dev_attr);
+	if (IS_ERR(soc_dev))
+		return PTR_ERR(soc_dev);
+
+	pr_info("Machine: %s\n", soc_dev_attr.machine);
+	pr_info("SoC family: %s\n", soc_dev_attr.family);
+	pr_info("SoC ID: %s, Revision: %s\n",
+		soc_dev_attr.soc_id, soc_dev_attr.revision);
+
+	return 0;
+}
+
+static int loongson2_guts_remove(struct platform_device *dev)
+{
+	soc_device_unregister(soc_dev);
+
+	return 0;
+}
+
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for Loongson-2 SoCs.
+ */
+static const struct of_device_id loongson2_guts_of_match[] = {
+	{ .compatible = "loongson,ls2k-chipid", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, loongson2_guts_of_match);
+
+static struct platform_driver loongson2_guts_driver = {
+	.driver = {
+		.name = "loongson2-guts",
+		.of_match_table = loongson2_guts_of_match,
+	},
+	.probe = loongson2_guts_probe,
+	.remove = loongson2_guts_remove,
+};
+
+static int __init loongson2_guts_init(void)
+{
+	return platform_driver_register(&loongson2_guts_driver);
+}
+core_initcall(loongson2_guts_init);
+
+static void __exit loongson2_guts_exit(void)
+{
+	platform_driver_unregister(&loongson2_guts_driver);
+}
+module_exit(loongson2_guts_exit);
-- 
2.31.1


^ permalink raw reply related	[relevance 6%]

* [tip: x86/urgent] MAINTAINERS: Add Intel TDX entry
@ 2023-11-03 21:34  6% tip-bot2 for Kirill A. Shutemov
  0 siblings, 0 replies; 200+ results
From: tip-bot2 for Kirill A. Shutemov @ 2023-11-03 21:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Dave Hansen, Kirill A. Shutemov, Kuppuswamy Sathyanarayanan,
	Kai Huang, x86, linux-kernel

The following commit has been merged into the x86/urgent branch of tip:

Commit-ID:     c692800cb2ef7a4f4940c68d765cd4649aff3e46
Gitweb:        https://git.kernel.org/tip/c692800cb2ef7a4f4940c68d765cd4649aff3e46
Author:        Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
AuthorDate:    Thu, 02 Nov 2023 02:33:14 +03:00
Committer:     Dave Hansen <dave.hansen@linux.intel.com>
CommitterDate: Fri, 03 Nov 2023 14:27:21 -07:00

MAINTAINERS: Add Intel TDX entry

Add myself as Intel TDX maintainer.

I drove upstreaming most of TDX code so far and I will continue
working on TDX for foreseeable future.

[ dhansen: * Add myself as a reviewer too
	   * Swap Maintained=>Supported.  I double
	     checked Kirill is still being paid
	   * Add drivers/virt/coco/tdx-guest ]

Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Acked-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Acked-by: Kai Huang <kai.huang@intel.com>
Link: https://lore.kernel.org/all/20231101233314.2567-1-kirill.shutemov%40linux.intel.com
---
 MAINTAINERS | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index dd5de54..b697020 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23460,6 +23460,20 @@ F:	arch/x86/kernel/dumpstack.c
 F:	arch/x86/kernel/stacktrace.c
 F:	arch/x86/kernel/unwind_*.c
 
+X86 TRUST DOMAIN EXTENSIONS (TDX)
+M:	Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+R:	Dave Hansen <dave.hansen@linux.intel.com>
+L:	x86@kernel.org
+L:	linux-coco@lists.linux.dev
+S:	Supported
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/tdx
+F:	arch/x86/boot/compressed/tdx*
+F:	arch/x86/coco/tdx/
+F:	arch/x86/include/asm/shared/tdx.h
+F:	arch/x86/include/asm/tdx.h
+F:	arch/x86/virt/vmx/tdx/
+F:	drivers/virt/coco/tdx-guest
+
 X86 VDSO
 M:	Andy Lutomirski <luto@kernel.org>
 L:	linux-kernel@vger.kernel.org

^ permalink raw reply related	[relevance 6%]

* [PATCH] MAINTAINERS: update fsverity git repo, list, and patchwork
@ 2023-01-16 23:22  6% ` Eric Biggers
  0 siblings, 0 replies; 200+ results
From: Eric Biggers @ 2023-01-16 23:22 UTC (permalink / raw)
  To: fsverity
  Cc: linux-fscrypt, linux-ext4, linux-f2fs-devel, linux-btrfs,
	linux-xfs, linux-fsdevel

From: Eric Biggers <ebiggers@google.com>

We're moving fsverity development to use its own git repo, mailing list,
and patchwork project, instead of reusing the fscrypt ones.  Update the
MAINTAINERS file accordingly.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 MAINTAINERS | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 42fc47c6edfd7..936cbdbc60eb1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8520,10 +8520,10 @@ F:	include/linux/fsnotify*.h
 FSVERITY: READ-ONLY FILE-BASED AUTHENTICITY PROTECTION
 M:	Eric Biggers <ebiggers@kernel.org>
 M:	Theodore Y. Ts'o <tytso@mit.edu>
-L:	linux-fscrypt@vger.kernel.org
+L:	fsverity@lists.linux.dev
 S:	Supported
-Q:	https://patchwork.kernel.org/project/linux-fscrypt/list/
-T:	git git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt.git fsverity
+Q:	https://patchwork.kernel.org/project/fsverity/list/
+T:	git https://git.kernel.org/pub/scm/fs/fsverity/linux.git
 F:	Documentation/filesystems/fsverity.rst
 F:	fs/verity/
 F:	include/linux/fsverity.h

base-commit: 5dc4c995db9eb45f6373a956eb1f69460e69e6d4
-- 
2.39.0


^ permalink raw reply related	[relevance 6%]

* [f2fs-dev] [PATCH] MAINTAINERS: update fsverity git repo, list, and patchwork
@ 2023-01-16 23:22  6% ` Eric Biggers
  0 siblings, 0 replies; 200+ results
From: Eric Biggers @ 2023-01-16 23:22 UTC (permalink / raw)
  To: fsverity
  Cc: linux-f2fs-devel, linux-xfs, linux-fscrypt, linux-fsdevel,
	linux-ext4, linux-btrfs

From: Eric Biggers <ebiggers@google.com>

We're moving fsverity development to use its own git repo, mailing list,
and patchwork project, instead of reusing the fscrypt ones.  Update the
MAINTAINERS file accordingly.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 MAINTAINERS | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 42fc47c6edfd7..936cbdbc60eb1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8520,10 +8520,10 @@ F:	include/linux/fsnotify*.h
 FSVERITY: READ-ONLY FILE-BASED AUTHENTICITY PROTECTION
 M:	Eric Biggers <ebiggers@kernel.org>
 M:	Theodore Y. Ts'o <tytso@mit.edu>
-L:	linux-fscrypt@vger.kernel.org
+L:	fsverity@lists.linux.dev
 S:	Supported
-Q:	https://patchwork.kernel.org/project/linux-fscrypt/list/
-T:	git git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt.git fsverity
+Q:	https://patchwork.kernel.org/project/fsverity/list/
+T:	git https://git.kernel.org/pub/scm/fs/fsverity/linux.git
 F:	Documentation/filesystems/fsverity.rst
 F:	fs/verity/
 F:	include/linux/fsverity.h

base-commit: 5dc4c995db9eb45f6373a956eb1f69460e69e6d4
-- 
2.39.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply related	[relevance 6%]

* [PATCH net 7/7] MAINTAINERS: update Geliang's email address
  @ 2024-02-08 18:03  6% ` Matthieu Baerts (NGI0)
  0 siblings, 0 replies; 200+ results
From: Matthieu Baerts (NGI0) @ 2024-02-08 18:03 UTC (permalink / raw)
  To: mptcp, Mat Martineau, Geliang Tang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Kishen Maloor, Florian Westphal,
	Peter Krystad, Dmytro Shytyi, Benjamin Hesmans
  Cc: netdev, linux-kernel, Christoph Paasch, Matthieu Baerts (NGI0)

From: Geliang Tang <geliang@kernel.org>

Update my email-address in MAINTAINERS and .mailmap entries to my
kernel.org account.

Suggested-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Geliang Tang <geliang@kernel.org>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
 .mailmap    | 9 +++++----
 MAINTAINERS | 2 +-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/.mailmap b/.mailmap
index 04998f7bda81..327e7eddd146 100644
--- a/.mailmap
+++ b/.mailmap
@@ -191,10 +191,11 @@ Gao Xiang <xiang@kernel.org> <gaoxiang25@huawei.com>
 Gao Xiang <xiang@kernel.org> <hsiangkao@aol.com>
 Gao Xiang <xiang@kernel.org> <hsiangkao@linux.alibaba.com>
 Gao Xiang <xiang@kernel.org> <hsiangkao@redhat.com>
-Geliang Tang <geliang.tang@linux.dev> <geliang.tang@suse.com>
-Geliang Tang <geliang.tang@linux.dev> <geliangtang@xiaomi.com>
-Geliang Tang <geliang.tang@linux.dev> <geliangtang@gmail.com>
-Geliang Tang <geliang.tang@linux.dev> <geliangtang@163.com>
+Geliang Tang <geliang@kernel.org> <geliang.tang@linux.dev>
+Geliang Tang <geliang@kernel.org> <geliang.tang@suse.com>
+Geliang Tang <geliang@kernel.org> <geliangtang@xiaomi.com>
+Geliang Tang <geliang@kernel.org> <geliangtang@gmail.com>
+Geliang Tang <geliang@kernel.org> <geliangtang@163.com>
 Georgi Djakov <djakov@kernel.org> <georgi.djakov@linaro.org>
 Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@de.ibm.com>
 Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index 42bdf99ed979..d7b5c622575a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15324,7 +15324,7 @@ K:	\bmdo_
 NETWORKING [MPTCP]
 M:	Matthieu Baerts <matttbe@kernel.org>
 M:	Mat Martineau <martineau@kernel.org>
-R:	Geliang Tang <geliang.tang@linux.dev>
+R:	Geliang Tang <geliang@kernel.org>
 L:	netdev@vger.kernel.org
 L:	mptcp@lists.linux.dev
 S:	Maintained

-- 
2.43.0


^ permalink raw reply related	[relevance 6%]

* [PATCH v4 1/2] soc: loongson: add GUTS driver for loongson-2 platforms
@ 2022-11-02  3:55  6% Yinbo Zhu
  2022-11-02  3:55  5% ` [PATCH v4 2/2] dt-bindings: soc: add loongson-2 chipid Yinbo Zhu
  0 siblings, 1 reply; 200+ results
From: Yinbo Zhu @ 2022-11-02  3:55 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, Yinbo Zhu

The global utilities block controls PCIE device enabling, alternate
function selection for multiplexed signals, consistency of HDA, USB
and PCIE, configuration of memory controller, rtc controller, lio
controller, and clock control.

This patch adds a driver to manage and access global utilities block
for loongarch architecture Loongson-2 SoCs. Initially only reading SVR
and registering soc device are supported. Other guts accesses, such
as reading PMON configuration by default, should eventually be added
into this driver as well.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
---
Change in v4:
		1. Remove menu information in Kconfig.

 MAINTAINERS                           |   6 +
 drivers/soc/Kconfig                   |   1 +
 drivers/soc/Makefile                  |   1 +
 drivers/soc/loongson/Kconfig          |  18 +++
 drivers/soc/loongson/Makefile         |   6 +
 drivers/soc/loongson/loongson2_guts.c | 189 ++++++++++++++++++++++++++
 6 files changed, 221 insertions(+)
 create mode 100644 drivers/soc/loongson/Kconfig
 create mode 100644 drivers/soc/loongson/Makefile
 create mode 100644 drivers/soc/loongson/loongson2_guts.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c9dc5ddbd9fe..20ce056ae207 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12041,6 +12041,12 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
 F:	drivers/pinctrl/pinctrl-loongson2.c
 
+LOONGSON-2 SOC SERIES GUTS DRIVER
+M:	Yinbo Zhu <zhuyinbo@loongson.cn>
+L:	loongarch@lists.linux.dev
+S:	Maintained
+F:	drivers/soc/loongson/loongson2_guts.c
+
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
 M:	Sathya Prakash <sathya.prakash@broadcom.com>
 M:	Sreekanth Reddy <sreekanth.reddy@broadcom.com>
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index e461c071189b..5dbb09f843f7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -13,6 +13,7 @@ source "drivers/soc/fujitsu/Kconfig"
 source "drivers/soc/imx/Kconfig"
 source "drivers/soc/ixp4xx/Kconfig"
 source "drivers/soc/litex/Kconfig"
+source "drivers/soc/loongson/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/microchip/Kconfig"
 source "drivers/soc/pxa/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 69ba6508cf2c..fff513bd522d 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -18,6 +18,7 @@ obj-y				+= imx/
 obj-y				+= ixp4xx/
 obj-$(CONFIG_SOC_XWAY)		+= lantiq/
 obj-$(CONFIG_LITEX_SOC_CONTROLLER) += litex/
+obj-y				+= loongson/
 obj-y				+= mediatek/
 obj-y				+= microchip/
 obj-y				+= pxa/
diff --git a/drivers/soc/loongson/Kconfig b/drivers/soc/loongson/Kconfig
new file mode 100644
index 000000000000..c60119b9d247
--- /dev/null
+++ b/drivers/soc/loongson/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Loongson-2 series SoC drivers
+#
+
+config LOONGSON2_GUTS
+	tristate "Loongson-2 GUTS"
+	depends on LOONGARCH || COMPILE_TEST
+	select SOC_BUS
+	help
+	  The global utilities block controls PCIE device enabling, alternate
+	  function selection for multiplexed signals, consistency of HDA, USB
+	  and PCIE, configuration of memory controller, rtc controller, lio
+	  controller, and clock control. This patch adds a driver to manage
+	  and access global utilities block for loongarch architecture Loongson-2
+	  SoCs. Initially only reading SVR and registering soc device are
+	  supported. Other guts accesses, such as reading PMON configuration by
+	  default, should eventually be added into this driver as well.
diff --git a/drivers/soc/loongson/Makefile b/drivers/soc/loongson/Makefile
new file mode 100644
index 000000000000..263c486df638
--- /dev/null
+++ b/drivers/soc/loongson/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Makefile for the Linux Kernel SoC Loongson-2 specific device drivers
+#
+
+obj-$(CONFIG_LOONGSON2_GUTS)		+= loongson2_guts.o
diff --git a/drivers/soc/loongson/loongson2_guts.c b/drivers/soc/loongson/loongson2_guts.c
new file mode 100644
index 000000000000..8f3d5465c7e8
--- /dev/null
+++ b/drivers/soc/loongson/loongson2_guts.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Author: Yinbo Zhu <zhuyinbo@loongson.cn>
+ * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/sys_soc.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+static struct soc_device_attribute soc_dev_attr;
+static struct soc_device *soc_dev;
+
+/*
+ * Global Utility Registers.
+ *
+ * Not all registers defined in this structure are available on all chips, so
+ * you are expected to know whether a given register actually exists on your
+ * chip before you access it.
+ *
+ * Also, some registers are similar on different chips but have slightly
+ * different names.  In these cases, one name is chosen to avoid extraneous
+ * #ifdefs.
+ */
+struct scfg_guts {
+	u32     svr;            /* Version Register */
+	u8      res0[4];
+	u16     feature;        /* Feature Register */
+	u32     vendor;         /* Vendor Register */
+	u8      res1[6];
+	u32     id;
+	u8      res2[0x3ff8 - 0x18];
+	u32     chip;
+};
+
+static struct guts {
+	struct scfg_guts __iomem *regs;
+	bool little_endian;
+} *guts;
+
+struct loongson2_soc_die_attr {
+	char	*die;
+	u32	svr;
+	u32	mask;
+};
+
+/* SoC die attribute definition for Loongson-2 platform */
+static const struct loongson2_soc_die_attr loongson2_soc_die[] = {
+
+	/*
+	 * LA-based SoCs Loongson-2 Series
+	 */
+
+	/* Die: 2k1000la, SoC: 2k1000la */
+	{ .die		= "2K1000LA",
+	  .svr		= 0x00000013,
+	  .mask		= 0x000000ff,
+	},
+	{ },
+};
+
+static const struct loongson2_soc_die_attr *loongson2_soc_die_match(
+	u32 svr, const struct loongson2_soc_die_attr *matches)
+{
+	while (matches->svr) {
+		if (matches->svr == (svr & matches->mask))
+			return matches;
+		matches++;
+	};
+
+	return NULL;
+}
+
+static u32 loongson2_guts_get_svr(void)
+{
+	u32 svr = 0;
+
+	if (!guts || !guts->regs)
+		return svr;
+
+	if (guts->little_endian)
+		svr = ioread32(&guts->regs->svr);
+	else
+		svr = ioread32be(&guts->regs->svr);
+
+	return svr;
+}
+
+static int loongson2_guts_probe(struct platform_device *pdev)
+{
+	struct device_node *root, *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	const struct loongson2_soc_die_attr *soc_die;
+	const char *machine;
+	u32 svr;
+
+	/* Initialize guts */
+	guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
+	if (!guts)
+		return -ENOMEM;
+
+	guts->little_endian = of_property_read_bool(np, "little-endian");
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	guts->regs = ioremap(res->start, res->end - res->start + 1);
+	if (IS_ERR(guts->regs))
+		return PTR_ERR(guts->regs);
+
+	/* Register soc device */
+	root = of_find_node_by_path("/");
+	if (of_property_read_string(root, "model", &machine))
+		of_property_read_string_index(root, "compatible", 0, &machine);
+	of_node_put(root);
+	if (machine)
+		soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+
+	svr = loongson2_guts_get_svr();
+	soc_die = loongson2_soc_die_match(svr, loongson2_soc_die);
+	if (soc_die) {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL,
+						     "Loongson %s", soc_die->die);
+	} else {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "Loongson");
+	}
+	if (!soc_dev_attr.family)
+		return -ENOMEM;
+	soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL,
+					     "svr:0x%08x", svr);
+	if (!soc_dev_attr.soc_id)
+		return -ENOMEM;
+	soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
+					       (svr >>  4) & 0xf, svr & 0xf);
+	if (!soc_dev_attr.revision)
+		return -ENOMEM;
+
+	soc_dev = soc_device_register(&soc_dev_attr);
+	if (IS_ERR(soc_dev))
+		return PTR_ERR(soc_dev);
+
+	pr_info("Machine: %s\n", soc_dev_attr.machine);
+	pr_info("SoC family: %s\n", soc_dev_attr.family);
+	pr_info("SoC ID: %s, Revision: %s\n",
+		soc_dev_attr.soc_id, soc_dev_attr.revision);
+
+	return 0;
+}
+
+static int loongson2_guts_remove(struct platform_device *dev)
+{
+	soc_device_unregister(soc_dev);
+
+	return 0;
+}
+
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for Loongson-2 SoCs.
+ */
+static const struct of_device_id loongson2_guts_of_match[] = {
+	{ .compatible = "loongson,ls2k-chipid", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, loongson2_guts_of_match);
+
+static struct platform_driver loongson2_guts_driver = {
+	.driver = {
+		.name = "loongson2-guts",
+		.of_match_table = loongson2_guts_of_match,
+	},
+	.probe = loongson2_guts_probe,
+	.remove = loongson2_guts_remove,
+};
+
+static int __init loongson2_guts_init(void)
+{
+	return platform_driver_register(&loongson2_guts_driver);
+}
+core_initcall(loongson2_guts_init);
+
+static void __exit loongson2_guts_exit(void)
+{
+	platform_driver_unregister(&loongson2_guts_driver);
+}
+module_exit(loongson2_guts_exit);
-- 
2.33.0


^ permalink raw reply related	[relevance 6%]

* [PATCH 2/9] mm/damon: rename CONFIG_DAMON_DBGFS to DAMON_DBGFS_DEPRECATED
  @ 2024-01-30  1:35  6% ` SeongJae Park
  2024-01-30  1:35  6% ` [PATCH 3/9] mm/damon/dbgfs: implement deprecation notice file SeongJae Park
  1 sibling, 0 replies; 200+ results
From: SeongJae Park @ 2024-01-30  1:35 UTC (permalink / raw)
  To: Andrew Morton; +Cc: SeongJae Park, damon, linux-mm, linux-kernel

DAMON debugfs interface is deprecated.  The fact has documented by
commit 5445fcbc4cda ("Docs/admin-guide/mm/damon/usage: add DAMON debugfs
interface deprecation notice").  Commit 620932cd2852 ("mm/damon/dbgfs:
print DAMON debugfs interface deprecation message") further started
printing a warning message when users still use it.  Many people don't
read documentation or kernel log, though.

Make the deprecation harder to be ignored using the approach of commit
eb07c4f39c3e ("mm/slab: rename CONFIG_SLAB to CONFIG_SLAB_DEPRECATED").
'make oldconfig' with 'CONFIG_DAMON_DBGFS=y' will get a new prompt with
the explicit deprecation notice on the name.  'make olddefconfig' with
'CONFIG_DAMON_DBGFS=y' will result in not building DAMON debugfs
interface.  If there is a real user of DAMON debugfs interface, they
will complain the change to the builder.

Signed-off-by: SeongJae Park <sj@kernel.org>
---
 mm/damon/Kconfig | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/mm/damon/Kconfig b/mm/damon/Kconfig
index 29f43fbc2eff..fecb8172410c 100644
--- a/mm/damon/Kconfig
+++ b/mm/damon/Kconfig
@@ -71,7 +71,7 @@ config DAMON_SYSFS_KUNIT_TEST
 
 	  If unsure, say N.
 
-config DAMON_DBGFS
+config DAMON_DBGFS_DEPRECATED
 	bool "DAMON debugfs interface (DEPRECATED!)"
 	depends on DAMON_VADDR && DAMON_PADDR && DEBUG_FS
 	help
@@ -84,6 +84,11 @@ config DAMON_DBGFS
 	  (DAMON_SYSFS).  If you depend on this and cannot move, please report
 	  your usecase to damon@lists.linux.dev and linux-mm@kvack.org.
 
+config DAMON_DBGFS
+	bool
+	default y
+	depends on DAMON_DBGFS_DEPRECATED
+
 config DAMON_DBGFS_KUNIT_TEST
 	bool "Test for damon debugfs interface" if !KUNIT_ALL_TESTS
 	depends on DAMON_DBGFS && KUNIT=y
-- 
2.39.2


^ permalink raw reply related	[relevance 6%]

* [PATCH v13 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-06-09  9:05  6% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-06-09  9:05 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui, tangyouling

Add maintainers for LoongArch KVM.

Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 27ef11624748..c2fbfd6ad4e5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11357,6 +11357,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git https://github.com/loongson/linux-loongarch-kvm
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 M:	Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
-- 
2.39.1


^ permalink raw reply related	[relevance 6%]

* [PATCH v13 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-06-09  9:08  6% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-06-09  9:08 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui, tangyouling

Add maintainers for LoongArch KVM.

Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 27ef11624748..c2fbfd6ad4e5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11357,6 +11357,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git https://github.com/loongson/linux-loongarch-kvm
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 M:	Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
-- 
2.39.1


^ permalink raw reply related	[relevance 6%]

* [PATCH 07/25] iommu/vt-d: Move include/linux/intel-iommu.h under iommu
  @ 2022-07-12  0:08  6% ` Lu Baolu
  0 siblings, 0 replies; 200+ results
From: Lu Baolu @ 2022-07-12  0:08 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: iommu, linux-kernel

This header file is private to the Intel IOMMU driver. Move it to the
driver folder.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Steve Wahl <steve.wahl@hpe.com>
Link: https://lore.kernel.org/r/20220514014322.2927339-8-baolu.lu@linux.intel.com
---
 include/linux/intel-iommu.h => drivers/iommu/intel/iommu.h | 0
 drivers/iommu/intel/trace.h                                | 3 ++-
 drivers/iommu/intel/cap_audit.c                            | 2 +-
 drivers/iommu/intel/debugfs.c                              | 2 +-
 drivers/iommu/intel/dmar.c                                 | 2 +-
 drivers/iommu/intel/iommu.c                                | 2 +-
 drivers/iommu/intel/irq_remapping.c                        | 2 +-
 drivers/iommu/intel/pasid.c                                | 2 +-
 drivers/iommu/intel/perf.c                                 | 2 +-
 drivers/iommu/intel/svm.c                                  | 2 +-
 MAINTAINERS                                                | 1 -
 11 files changed, 10 insertions(+), 10 deletions(-)
 rename include/linux/intel-iommu.h => drivers/iommu/intel/iommu.h (100%)

diff --git a/include/linux/intel-iommu.h b/drivers/iommu/intel/iommu.h
similarity index 100%
rename from include/linux/intel-iommu.h
rename to drivers/iommu/intel/iommu.h
diff --git a/drivers/iommu/intel/trace.h b/drivers/iommu/intel/trace.h
index 25cb7f88e1a2..93d96f93a89b 100644
--- a/drivers/iommu/intel/trace.h
+++ b/drivers/iommu/intel/trace.h
@@ -13,7 +13,8 @@
 #define _TRACE_INTEL_IOMMU_H
 
 #include <linux/tracepoint.h>
-#include <linux/intel-iommu.h>
+
+#include "iommu.h"
 
 #define MSG_MAX		256
 
diff --git a/drivers/iommu/intel/cap_audit.c b/drivers/iommu/intel/cap_audit.c
index 71596fc62822..3ee68393122f 100644
--- a/drivers/iommu/intel/cap_audit.c
+++ b/drivers/iommu/intel/cap_audit.c
@@ -10,7 +10,7 @@
 
 #define pr_fmt(fmt)	"DMAR: " fmt
 
-#include <linux/intel-iommu.h>
+#include "iommu.h"
 #include "cap_audit.h"
 
 static u64 intel_iommu_cap_sanity;
diff --git a/drivers/iommu/intel/debugfs.c b/drivers/iommu/intel/debugfs.c
index ed796eea4581..d927ef10641b 100644
--- a/drivers/iommu/intel/debugfs.c
+++ b/drivers/iommu/intel/debugfs.c
@@ -10,11 +10,11 @@
 
 #include <linux/debugfs.h>
 #include <linux/dmar.h>
-#include <linux/intel-iommu.h>
 #include <linux/pci.h>
 
 #include <asm/irq_remapping.h>
 
+#include "iommu.h"
 #include "pasid.h"
 #include "perf.h"
 
diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index f91b45be1d92..2a5e0f91e647 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -19,7 +19,6 @@
 #include <linux/pci.h>
 #include <linux/dmar.h>
 #include <linux/iova.h>
-#include <linux/intel-iommu.h>
 #include <linux/timer.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
@@ -31,6 +30,7 @@
 #include <linux/limits.h>
 #include <asm/irq_remapping.h>
 
+#include "iommu.h"
 #include "../irq_remapping.h"
 #include "perf.h"
 #include "trace.h"
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index c70948021e8e..10bda4bec8fe 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -17,7 +17,6 @@
 #include <linux/dma-direct.h>
 #include <linux/dma-iommu.h>
 #include <linux/dmi.h>
-#include <linux/intel-iommu.h>
 #include <linux/intel-svm.h>
 #include <linux/memory.h>
 #include <linux/pci.h>
@@ -26,6 +25,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/tboot.h>
 
+#include "iommu.h"
 #include "../irq_remapping.h"
 #include "../iommu-sva-lib.h"
 #include "pasid.h"
diff --git a/drivers/iommu/intel/irq_remapping.c b/drivers/iommu/intel/irq_remapping.c
index a67319597884..2e9683e970f8 100644
--- a/drivers/iommu/intel/irq_remapping.c
+++ b/drivers/iommu/intel/irq_remapping.c
@@ -10,7 +10,6 @@
 #include <linux/hpet.h>
 #include <linux/pci.h>
 #include <linux/irq.h>
-#include <linux/intel-iommu.h>
 #include <linux/acpi.h>
 #include <linux/irqdomain.h>
 #include <linux/crash_dump.h>
@@ -21,6 +20,7 @@
 #include <asm/irq_remapping.h>
 #include <asm/pci-direct.h>
 
+#include "iommu.h"
 #include "../irq_remapping.h"
 #include "cap_audit.h"
 
diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
index 17cad7c1f62d..43f090381ec7 100644
--- a/drivers/iommu/intel/pasid.c
+++ b/drivers/iommu/intel/pasid.c
@@ -12,13 +12,13 @@
 #include <linux/bitops.h>
 #include <linux/cpufeature.h>
 #include <linux/dmar.h>
-#include <linux/intel-iommu.h>
 #include <linux/iommu.h>
 #include <linux/memory.h>
 #include <linux/pci.h>
 #include <linux/pci-ats.h>
 #include <linux/spinlock.h>
 
+#include "iommu.h"
 #include "pasid.h"
 
 /*
diff --git a/drivers/iommu/intel/perf.c b/drivers/iommu/intel/perf.c
index 0e8e03252d92..94ee70ac38e3 100644
--- a/drivers/iommu/intel/perf.c
+++ b/drivers/iommu/intel/perf.c
@@ -9,8 +9,8 @@
  */
 
 #include <linux/spinlock.h>
-#include <linux/intel-iommu.h>
 
+#include "iommu.h"
 #include "perf.h"
 
 static DEFINE_SPINLOCK(latency_lock);
diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c
index 70b40d007a52..580713aa9e07 100644
--- a/drivers/iommu/intel/svm.c
+++ b/drivers/iommu/intel/svm.c
@@ -5,7 +5,6 @@
  * Authors: David Woodhouse <dwmw2@infradead.org>
  */
 
-#include <linux/intel-iommu.h>
 #include <linux/mmu_notifier.h>
 #include <linux/sched.h>
 #include <linux/sched/mm.h>
@@ -22,6 +21,7 @@
 #include <asm/page.h>
 #include <asm/fpu/api.h>
 
+#include "iommu.h"
 #include "pasid.h"
 #include "perf.h"
 #include "../iommu-sva-lib.h"
diff --git a/MAINTAINERS b/MAINTAINERS
index ead381fdfc5a..fa2cde7dc644 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9998,7 +9998,6 @@ L:	iommu@lists.linux.dev
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
 F:	drivers/iommu/intel/
-F:	include/linux/intel-iommu.h
 F:	include/linux/intel-svm.h
 
 INTEL IOP-ADMA DMA DRIVER
-- 
2.25.1


^ permalink raw reply related	[relevance 6%]

* [PATCH v11 31/31] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-05-22  3:12  6% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-05-22  3:12 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui

Add maintainers for LoongArch KVM.

Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 27ef11624748..0b6fe590f275 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11357,6 +11357,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.com>
+M:	Bibo Mao <maobibo@loongson.com>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git https://github.com/loongson/linux-loongarch-kvm
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 M:	Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
-- 
2.39.1


^ permalink raw reply related	[relevance 6%]

* [PATCH v12 31/31] LoongArch: KVM: Add maintainers for LoongArch KVM
  @ 2023-05-30  1:52  6% ` Tianrui Zhao
  0 siblings, 0 replies; 200+ results
From: Tianrui Zhao @ 2023-05-30  1:52 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Huacai Chen, WANG Xuerui, Greg Kroah-Hartman,
	loongarch, Jens Axboe, Mark Brown, Alex Deucher, Oliver Upton,
	maobibo, Xi Ruoyao, zhaotianrui

Add maintainers for LoongArch KVM.

Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 27ef11624748..c2fbfd6ad4e5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11357,6 +11357,18 @@ F:	include/kvm/arm_*
 F:	tools/testing/selftests/kvm/*/aarch64/
 F:	tools/testing/selftests/kvm/aarch64/
 
+KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
+M:	Tianrui Zhao <zhaotianrui@loongson.cn>
+M:	Bibo Mao <maobibo@loongson.cn>
+M:	Huacai Chen <chenhuacai@kernel.org>
+L:	kvm@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+T:	git https://github.com/loongson/linux-loongarch-kvm
+F:	arch/loongarch/include/asm/kvm*
+F:	arch/loongarch/include/uapi/asm/kvm*
+F:	arch/loongarch/kvm/
+
 KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
 M:	Huacai Chen <chenhuacai@kernel.org>
 M:	Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
-- 
2.39.1


^ permalink raw reply related	[relevance 6%]

* Re: Is the data rate estimation for 5GHz channels overly pessimistic?
  @ 2023-10-15 19:40  6%         ` Simonas Kazlauskas
    0 siblings, 1 reply; 200+ results
From: Simonas Kazlauskas @ 2023-10-15 19:40 UTC (permalink / raw)
  To: Denis Kenzior; +Cc: James Prestwood, iwd

[-- Attachment #1: Type: text/plain, Size: 3210 bytes --]

Hey,

Denis Kenzior wrote:
>It may be we screwed something up with HE since hardware was still pretty 
>rare when the feature was developed.  But we do treat RSSI values below -82 
>as almost unusable.  Perhaps this needs to be tweaked for newer hardware.
>
>If you want to get your hands dirty, it should be fairly easy to 
>modify unit/test-band.c to test what our estimate code does with your 
>specific circumstances.
>
>The local HE capabilities can be found via 'iw phy', looking at what 
>iwd prints at start, or using iwmon.  Similarly, remote capabilities 
>can be sniffed using iwmon and running an iwd scan or 'iw scan 
>trigger'.
>
>Me or James can walk you through all this if needed.

Thanks for offering. I have cracked open the file, and just started playing 
around by adding a new `he_test_data` structure. Alas, I’m really hazy on what 
I ought to be filing into the `capabilities` and `he_capabilities` fields. My 
initial guess is something like this, based on one of the other tests around:

+/* 5GHz, 40MHz, MCS 11, NSS 1 */
+const struct he_test_data he_test_5_40mhz_mcs_5_nss_1 = {
+	.freq = BAND_FREQ_5_GHZ,
+	.rssi = -76,
+	.expected_rate = 275200000ULL,
+	.capabilities = {
+		.he_mcs_set = { HE_MCS_SET(MCS11, 1), MCS_UNSUP },
+		.he_phy_capa = { HE_PHY_CAPA(0x00) },
+		.iftypes = 1 << NETDEV_IFTYPE_STATION,
+	},
+	.he_capabilities = {
+		22, IE_TYPE_HE_CAPABILITIES - 256, HE_MAC_CAPA,
+		HE_PHY_CAPA(0x00), MCS_UNSUP, HE_MCS_SET(MCS11, 1)
+	},
+};

This computes a rate of `25800000`, which I’m guessing corresponds to 
25.8Mbps, perhaps? That’s fair I guess, since the only thing I really really 
changed in there compared to the other tests is the `MCS11` (that’s supported 
by AX201) and the `rssi`. There clearly are plenty of other fields that I 
should be filling in here, I feel, if I wanted to accurately represent my 
hardware.

I think I managed to grab the capabilities of both the AP and the client using 
your instructions, but I’m really unclear on how to go from the output from 
`iwmon` to fields in this struct. My best guess right now is to actually run 
`iwd` under a gdb and place some breakpoints in the scanning code to extract 
the capabilities. Would that make sense, or is there a better way to fill in 
these fields?

(As I’m writing this mail, I realize now that I probably want to somehow 
specify NSS=2 for `2x2` MIMO…?)

Another thing that confuses me a great deal is the fact that the scan results 
with my APs don’t actually show any of the HE capabilities, only the HT and 
VHT ones (see attached sample from the `iwmon` output.) I also tried scanning 
an Android hotspot on a reasonably recent phone, and although the set of MCS 
supported were different, the output still contains only HT and VHT 
capabilities. I would love to attach my pcap here, but unfortunately I also 
have no clue how to sanitize it, so I’m going to attach an excerpt from 
`iwmon`’s output for the time being. Is this expected, or could this perhaps 
be at least part of the problem I’m seeing? Is it possible that an AP could 
not advertise HE capabilities at scan time, but for HE to still be used after 
authentication occurs?

Thank you,
S.

[-- Attachment #2: x --]
[-- Type: text/plain, Size: 452 bytes --]

/* 5GHz, 40MHz, MCS 11, NSS 1 */
const struct he_test_data he_test_5_40mhz_mcs_5_nss_1 = {
	.freq = BAND_FREQ_5_GHZ,
	.rssi = -76,
	.expected_rate = 275200000ULL,
	.capabilities = {
		.he_mcs_set = { HE_MCS_SET(MCS11, 1), MCS_UNSUP },
		.he_phy_capa = { HE_PHY_CAPA(0x00) },
		.iftypes = 1 << NETDEV_IFTYPE_STATION,
	},
	.he_capabilities = {
		22, IE_TYPE_HE_CAPABILITIES - 256, HE_MAC_CAPA,
		HE_PHY_CAPA(0x00), MCS_UNSUP, HE_MCS_SET(MCS11, 1)
	},
};

^ permalink raw reply	[relevance 6%]

* + docs-mm-damon-maintainer-profile-fix-typos-and-grammar-errors.patch added to mm-unstable branch
@ 2023-05-25 21:50  6% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2023-05-25 21:50 UTC (permalink / raw)
  To: mm-commits, corbet, sj, akpm


The patch titled
     Subject: Docs/mm/damon/maintainer-profile: fix typos and grammar errors
has been added to the -mm mm-unstable branch.  Its filename is
     docs-mm-damon-maintainer-profile-fix-typos-and-grammar-errors.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/docs-mm-damon-maintainer-profile-fix-typos-and-grammar-errors.patch

This patch will later appear in the mm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: Docs/mm/damon/maintainer-profile: fix typos and grammar errors
Date: Thu, 25 May 2023 21:43:06 +0000

Fix a few typos and grammar erros in DAMON Maintainer Profile document.

Link: https://lkml.kernel.org/r/20230525214314.5204-3-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 Documentation/mm/damon/maintainer-profile.rst |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/Documentation/mm/damon/maintainer-profile.rst~docs-mm-damon-maintainer-profile-fix-typos-and-grammar-errors
+++ a/Documentation/mm/damon/maintainer-profile.rst
@@ -3,7 +3,7 @@
 DAMON Maintainer Entry Profile
 ==============================
 
-The DAMON subsystem covers the files that listed in 'DATA ACCESS MONITOR'
+The DAMON subsystem covers the files that are listed in 'DATA ACCESS MONITOR'
 section of 'MAINTAINERS' file.
 
 The mailing lists for the subsystem are damon@lists.linux.dev and
@@ -15,7 +15,7 @@ SCM Trees
 
 There are multiple Linux trees for DAMON development.  Patches under
 development or testing are queued in damon/next [2]_ by the DAMON maintainer.
-Suffieicntly reviewed patches will be queued in mm-unstable [1]_ by the memory
+Sufficiently reviewed patches will be queued in mm-unstable [1]_ by the memory
 management subsystem maintainer.  After more sufficient tests, the patches will
 be queued in mm-stable [3]_ , and finally pull-requested to the mainline by the
 memory management subsystem maintainer.
_

Patches currently in -mm which might be from sj@kernel.org are

docs-mm-damon-faq-remove-old-questions.patch
docs-mm-damon-maintainer-profile-fix-typos-and-grammar-errors.patch
docs-mm-damon-design-add-a-section-for-overall-architecture.patch
docs-mm-damon-design-update-the-layout-based-on-the-layers.patch
docs-mm-damon-design-rewrite-configurable-layers.patch
docs-mm-damon-design-add-a-section-for-the-relation-between-core-and-modules-layer.patch
docs-mm-damon-design-add-sections-for-basic-parts-of-damos.patch
docs-mm-damon-design-add-sections-for-advanced-features-of-damos.patch
docs-mm-damon-design-add-a-section-for-damon-core-api.patch
docs-mm-damon-design-add-a-section-for-the-modules-layer.patch


^ permalink raw reply	[relevance 6%]

* + documentation-llvm-update-irc-location.patch added to -mm tree
@ 2021-08-31 22:48  6% akpm
  0 siblings, 0 replies; 200+ results
From: akpm @ 2021-08-31 22:48 UTC (permalink / raw)
  To: keescook, masahiroy, mm-commits, nathan, ndesaulniers,
	samitolvanen


The patch titled
     Subject: Documentation/llvm: update IRC location
has been added to the -mm tree.  Its filename is
     documentation-llvm-update-irc-location.patch

This patch should soon appear at
    https://ozlabs.org/~akpm/mmots/broken-out/documentation-llvm-update-irc-location.patch
and later at
    https://ozlabs.org/~akpm/mmotm/broken-out/documentation-llvm-update-irc-location.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next and is updated
there every 3-4 working days

------------------------------------------------------
From: Nathan Chancellor <nathan@kernel.org>
Subject: Documentation/llvm: update IRC location

This should have been done with commit 91ed3ed0f798 ("MAINTAINERS: update
ClangBuiltLinux IRC chat") but I did not realize it was in two separate
spots.

Link: https://lkml.kernel.org/r/20210825211823.6406-3-nathan@kernel.org
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 Documentation/kbuild/llvm.rst |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/Documentation/kbuild/llvm.rst~documentation-llvm-update-irc-location
+++ a/Documentation/kbuild/llvm.rst
@@ -114,7 +114,7 @@ Getting Help
 - `Mailing List <https://lore.kernel.org/llvm/>`_: <llvm@lists.linux.dev>
 - `Old Mailing List Archives <https://groups.google.com/g/clang-built-linux>`_
 - `Issue Tracker <https://github.com/ClangBuiltLinux/linux/issues>`_
-- IRC: #clangbuiltlinux on chat.freenode.net
+- IRC: #clangbuiltlinux on irc.libera.chat
 - `Telegram <https://t.me/ClangBuiltLinux>`_: @ClangBuiltLinux
 - `Wiki <https://github.com/ClangBuiltLinux/linux/wiki>`_
 - `Beginner Bugs <https://github.com/ClangBuiltLinux/linux/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22>`_
_

Patches currently in -mm which might be from nathan@kernel.org are

mm-hugetlb-add-support-for-mempolicy-mpol_preferred_many-fix-fix.patch
maintainers-update-clangbuiltlinux-mailing-list.patch
documentation-llvm-update-mailing-list.patch
documentation-llvm-update-irc-location.patch


^ permalink raw reply	[relevance 6%]

* [PATCH v1 1/2] soc: loongson: add GUTS driver for loongson2 platforms
@ 2022-10-24 10:58  6% Yinbo Zhu
  2022-10-24 10:58  5% ` [PATCH v1 2/2] dt-bindings: soc: add loongson2 guts Yinbo Zhu
  0 siblings, 1 reply; 200+ results
From: Yinbo Zhu @ 2022-10-24 10:58 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Arnd Bergmann, Hector Martin,
	Lubomir Rintel, Conor Dooley, Linus Walleij, Hitomi Hasegawa,
	Heiko Stuebner, Brian Norris, Sven Peter, loongarch, devicetree,
	linux-kernel, Yinbo Zhu

The global utilities block controls PCIE device enabling, alternate
function selection for multiplexed signals, consistency of HDA, USB
and PCIE, configuration of memory controller, rtc controller, lio
controller, and clock control.

This patch adds a driver to manage and access global utilities block.
Initially only reading SVR and registering soc device are supported.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
---
 MAINTAINERS                             |   7 +
 drivers/soc/Kconfig                     |   1 +
 drivers/soc/Makefile                    |   1 +
 drivers/soc/loongson/Kconfig            |  17 +++
 drivers/soc/loongson/Makefile           |   6 +
 drivers/soc/loongson/loongson2_guts.c   | 168 ++++++++++++++++++++++++
 include/linux/loongson/loongson2_guts.h |  35 +++++
 7 files changed, 235 insertions(+)
 create mode 100644 drivers/soc/loongson/Kconfig
 create mode 100644 drivers/soc/loongson/Makefile
 create mode 100644 drivers/soc/loongson/loongson2_guts.c
 create mode 100644 include/linux/loongson/loongson2_guts.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 2d002509fc65..f032096d5251 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11930,6 +11930,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
 F:	drivers/pinctrl/pinctrl-loongson2.c
 
+LOONGSON2 SOC SERIES GUTS DRIVER
+M:	Yinbo Zhu <zhuyinbo@loongson.cn>
+L:	loongarch@lists.linux.dev
+S:	Maintained
+F:	drivers/soc/loongson/loongson2_guts.c
+F:	include/linux/loongson/loongson2_guts.h
+
 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
 M:	Sathya Prakash <sathya.prakash@broadcom.com>
 M:	Sreekanth Reddy <sreekanth.reddy@broadcom.com>
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index e461c071189b..5dbb09f843f7 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -13,6 +13,7 @@ source "drivers/soc/fujitsu/Kconfig"
 source "drivers/soc/imx/Kconfig"
 source "drivers/soc/ixp4xx/Kconfig"
 source "drivers/soc/litex/Kconfig"
+source "drivers/soc/loongson/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/microchip/Kconfig"
 source "drivers/soc/pxa/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 69ba6508cf2c..fff513bd522d 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -18,6 +18,7 @@ obj-y				+= imx/
 obj-y				+= ixp4xx/
 obj-$(CONFIG_SOC_XWAY)		+= lantiq/
 obj-$(CONFIG_LITEX_SOC_CONTROLLER) += litex/
+obj-y				+= loongson/
 obj-y				+= mediatek/
 obj-y				+= microchip/
 obj-y				+= pxa/
diff --git a/drivers/soc/loongson/Kconfig b/drivers/soc/loongson/Kconfig
new file mode 100644
index 000000000000..5b97071ff352
--- /dev/null
+++ b/drivers/soc/loongson/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Loongson2 series SoC drivers
+#
+
+menu "Loongson2 series SoC drivers"
+
+config LOONGSON2_GUTS
+	tristate "LOONGSON2 GUTS"
+	select SOC_BUS
+	help
+	  The global utilities block controls PCIE device enabling, alternate
+	  function selection for multiplexed signals, consistency of HDA, USB
+	  and PCIE, configuration of memory controller, rtc controller, lio
+	  controller, and clock control. This patch adds a driver to manage
+	  and access global utilities block. Initially only reading SVR and
+	  registering soc device are supported.
diff --git a/drivers/soc/loongson/Makefile b/drivers/soc/loongson/Makefile
new file mode 100644
index 000000000000..acfc90a624c9
--- /dev/null
+++ b/drivers/soc/loongson/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Makefile for the Linux Kernel SoC loongson2 specific device drivers
+#
+
+obj-$(CONFIG_LOONGSON2_GUTS)		+= loongson2_guts.o
diff --git a/drivers/soc/loongson/loongson2_guts.c b/drivers/soc/loongson/loongson2_guts.c
new file mode 100644
index 000000000000..fc4af7d32174
--- /dev/null
+++ b/drivers/soc/loongson/loongson2_guts.c
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Author: Yinbo Zhu <zhuyinbo@loongson.cn>
+ * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/sys_soc.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/loongson/loongson2_guts.h>
+
+static struct soc_device_attribute soc_dev_attr;
+static struct soc_device *soc_dev;
+
+static struct guts {
+	struct scfg_guts __iomem *regs;
+	bool little_endian;
+} *guts;
+
+struct loongson2_soc_die_attr {
+	char	*die;
+	u32	svr;
+	u32	mask;
+};
+
+/* SoC die attribute definition for loongson platform */
+static const struct loongson2_soc_die_attr loongson2_soc_die[] = {
+
+	/*
+	 * LA-based SoCs Loongson2 Series
+	 */
+
+	/* Die: 2k1000la, SoC: 2k1000la */
+	{ .die		= "2K1000LA",
+	  .svr		= 0x00000013,
+	  .mask		= 0x000000ff,
+	},
+	{ },
+};
+
+static const struct loongson2_soc_die_attr *loongson2_soc_die_match(
+	u32 svr, const struct loongson2_soc_die_attr *matches)
+{
+	while (matches->svr) {
+		if (matches->svr == (svr & matches->mask))
+			return matches;
+		matches++;
+	};
+
+	return NULL;
+}
+
+static u32 loongson2_guts_get_svr(void)
+{
+	u32 svr = 0;
+
+	if (!guts || !guts->regs)
+		return svr;
+
+	if (guts->little_endian)
+		svr = ioread32(&guts->regs->svr);
+	else
+		svr = ioread32be(&guts->regs->svr);
+
+	return svr;
+}
+
+static int loongson2_guts_probe(struct platform_device *pdev)
+{
+	struct device_node *root, *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	const struct loongson2_soc_die_attr *soc_die;
+	const char *machine;
+	u32 svr;
+
+	/* Initialize guts */
+	guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
+	if (!guts)
+		return -ENOMEM;
+
+	guts->little_endian = of_property_read_bool(np, "little-endian");
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	guts->regs = ioremap(res->start, res->end - res->start + 1);
+	if (IS_ERR(guts->regs))
+		return PTR_ERR(guts->regs);
+
+	/* Register soc device */
+	root = of_find_node_by_path("/");
+	if (of_property_read_string(root, "model", &machine))
+		of_property_read_string_index(root, "compatible", 0, &machine);
+	of_node_put(root);
+	if (machine)
+		soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+
+	svr = loongson2_guts_get_svr();
+	soc_die = loongson2_soc_die_match(svr, loongson2_soc_die);
+	if (soc_die) {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL,
+						     "Loongson %s", soc_die->die);
+	} else {
+		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "Loongson");
+	}
+	if (!soc_dev_attr.family)
+		return -ENOMEM;
+	soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL,
+					     "svr:0x%08x", svr);
+	if (!soc_dev_attr.soc_id)
+		return -ENOMEM;
+	soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
+					       (svr >>  4) & 0xf, svr & 0xf);
+	if (!soc_dev_attr.revision)
+		return -ENOMEM;
+
+	soc_dev = soc_device_register(&soc_dev_attr);
+	if (IS_ERR(soc_dev))
+		return PTR_ERR(soc_dev);
+
+	pr_info("Machine: %s\n", soc_dev_attr.machine);
+	pr_info("SoC family: %s\n", soc_dev_attr.family);
+	pr_info("SoC ID: %s, Revision: %s\n",
+		soc_dev_attr.soc_id, soc_dev_attr.revision);
+
+	return 0;
+}
+
+static int loongson2_guts_remove(struct platform_device *dev)
+{
+	soc_device_unregister(soc_dev);
+
+	return 0;
+}
+
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for Loongson2 SoCs.
+ */
+static const struct of_device_id loongson2_guts_of_match[] = {
+	{ .compatible = "loongson,ls2k-guts", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, loongson2_guts_of_match);
+
+static struct platform_driver loongson2_guts_driver = {
+	.driver = {
+		.name = "loongson2-guts",
+		.of_match_table = loongson2_guts_of_match,
+	},
+	.probe = loongson2_guts_probe,
+	.remove = loongson2_guts_remove,
+};
+
+static int __init loongson2_guts_init(void)
+{
+	return platform_driver_register(&loongson2_guts_driver);
+}
+core_initcall(loongson2_guts_init);
+
+static void __exit loongson2_guts_exit(void)
+{
+	platform_driver_unregister(&loongson2_guts_driver);
+}
+module_exit(loongson2_guts_exit);
diff --git a/include/linux/loongson/loongson2_guts.h b/include/linux/loongson/loongson2_guts.h
new file mode 100644
index 000000000000..4e5de3ff05c3
--- /dev/null
+++ b/include/linux/loongson/loongson2_guts.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Author: Yinbo Zhu <zhuyinbo@loongson.cn>
+ * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
+ */
+
+#ifndef __LOONGSON2_GUTS_H__
+#define __LOONGSON2_GUTS_H__
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+/**
+ * Global Utility Registers.
+ *
+ * Not all registers defined in this structure are available on all chips, so
+ * you are expected to know whether a given register actually exists on your
+ * chip before you access it.
+ *
+ * Also, some registers are similar on different chips but have slightly
+ * different names.  In these cases, one name is chosen to avoid extraneous
+ * #ifdefs.
+ */
+struct scfg_guts {
+	u32	svr;		/* Version Register */
+	u8	res0[4];
+	u16	feature;	/* Feature Register */
+	u32	vendor;		/* Vendor Register */
+	u8	res1[6];
+	u32	id;
+	u8	res2[0x3ff8 - 0x18];
+	u32	chip;
+} __packed;
+
+#endif
-- 
2.20.1


^ permalink raw reply related	[relevance 6%]

* [PATCH 1/2] hwmon: add ChromeOS EC driver
  @ 2024-05-07 13:57  6% ` Thomas Weißschuh
  0 siblings, 0 replies; 200+ results
From: Thomas Weißschuh @ 2024-05-07 13:57 UTC (permalink / raw)
  To: Jean Delvare, Guenter Roeck, Benson Leung, Lee Jones
  Cc: Guenter Roeck, linux-kernel, linux-hwmon, chrome-platform,
	Dustin Howett, Mario Limonciello, Moritz Fischer,
	Thomas Weißschuh

The ChromeOS Embedded Controller exposes fan speed and temperature
readings.
Expose this data through the hwmon subsystem.

The driver is designed to be probed via the cros_ec mfd device.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 Documentation/hwmon/cros_ec_hwmon.rst |  26 ++++
 Documentation/hwmon/index.rst         |   1 +
 MAINTAINERS                           |   8 +
 drivers/hwmon/Kconfig                 |  11 ++
 drivers/hwmon/Makefile                |   1 +
 drivers/hwmon/cros_ec_hwmon.c         | 279 ++++++++++++++++++++++++++++++++++
 6 files changed, 326 insertions(+)

diff --git a/Documentation/hwmon/cros_ec_hwmon.rst b/Documentation/hwmon/cros_ec_hwmon.rst
new file mode 100644
index 000000000000..aeb88c79d11b
--- /dev/null
+++ b/Documentation/hwmon/cros_ec_hwmon.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Kernel driver cros_ec_hwmon
+===========================
+
+Supported chips:
+
+  * ChromeOS embedded controllers connected via LPC
+
+    Prefix: 'cros_ec'
+
+    Addresses scanned: -
+
+Author:
+
+  - Thomas Weißschuh <linux@weissschuh.net>
+
+Description
+-----------
+
+This driver implements support for hardware monitoring commands exposed by the
+ChromeOS embedded controller used in Chromebooks and other devices.
+
+The channel labels exposed via hwmon are retrieved from the EC itself.
+
+Fan and temperature readings are supported.
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 1ca7a4fe1f8f..355a83e66928 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -57,6 +57,7 @@ Hardware Monitoring Kernel Drivers
    coretemp
    corsair-cpro
    corsair-psu
+   cros_ec_hwmon
    da9052
    da9055
    dell-smm-hwmon
diff --git a/MAINTAINERS b/MAINTAINERS
index c23fda1aa1f0..aa5689169eca 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4988,6 +4988,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
 F:	sound/soc/codecs/cros_ec_codec.*
 
+CHROMEOS EC HARDWARE MONITORING
+M:	Thomas Weißschuh <thomas@weissschuh.net>
+L:	chrome-platform@lists.linux.dev
+L:	linux-hwmon@vger.kernel.org
+S:	Maintained
+F:	Documentation/hwmon/chros_ec_hwmon.rst
+F:	drivers/hwmon/cros_ec_hwmon.c
+
 CHROMEOS EC SUBDRIVERS
 M:	Benson Leung <bleung@chromium.org>
 R:	Guenter Roeck <groeck@chromium.org>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 83945397b6eb..c1284d42697f 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -506,6 +506,17 @@ config SENSORS_CORSAIR_PSU
 	  This driver can also be built as a module. If so, the module
 	  will be called corsair-psu.
 
+config SENSORS_CROS_EC
+	tristate "ChromeOS Embedded Controller sensors"
+	depends on MFD_CROS_EC_DEV
+	default MFD_CROS_EC_DEV
+	help
+	  If you say yes here you get support for ChromeOS Embedded Controller
+	  sensors.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called cros_ec_hwmon.
+
 config SENSORS_DRIVETEMP
 	tristate "Hard disk drives with temperature sensors"
 	depends on SCSI && ATA
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 5c31808f6378..8519a6b36c00 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_SENSORS_CHIPCAP2) += chipcap2.o
 obj-$(CONFIG_SENSORS_CORETEMP)	+= coretemp.o
 obj-$(CONFIG_SENSORS_CORSAIR_CPRO) += corsair-cpro.o
 obj-$(CONFIG_SENSORS_CORSAIR_PSU) += corsair-psu.o
+obj-$(CONFIG_SENSORS_CROS_EC)	+= cros_ec_hwmon.o
 obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
 obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o
 obj-$(CONFIG_SENSORS_DELL_SMM)	+= dell-smm-hwmon.o
diff --git a/drivers/hwmon/cros_ec_hwmon.c b/drivers/hwmon/cros_ec_hwmon.c
new file mode 100644
index 000000000000..9588df202a74
--- /dev/null
+++ b/drivers/hwmon/cros_ec_hwmon.c
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  ChromesOS EC driver for hwmon
+ *
+ *  Copyright (C) 2024 Thomas Weißschuh <linux@weissschuh.net>
+ */
+
+#include <linux/device.h>
+#include <linux/hwmon.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/cros_ec_commands.h>
+#include <linux/platform_data/cros_ec_proto.h>
+#include <linux/units.h>
+
+#define DRV_NAME	"cros-ec-hwmon"
+
+struct cros_ec_hwmon_priv {
+	struct cros_ec_device *cros_ec;
+	u8 thermal_version;
+	const char *temp_sensor_names[EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES];
+};
+
+static int cros_ec_hwmon_read_fan_speed(struct cros_ec_device *cros_ec, u8 index, u16 *speed)
+{
+	int ret;
+	u16 data;
+
+	if (index >= EC_FAN_SPEED_ENTRIES)
+		return -ENODEV;
+
+	ret = cros_ec->cmd_readmem(cros_ec, EC_MEMMAP_FAN + index * 2, 2, &data);
+	if (ret < 0)
+		return ret;
+
+	data = le16_to_cpu(data);
+
+	if (data == EC_FAN_SPEED_NOT_PRESENT)
+		return -ENODEV;
+
+	*speed = data;
+	return 0;
+}
+
+static int cros_ec_hwmon_read_temp(struct cros_ec_device *cros_ec, u8 thermal_version,
+				   u8 index, u8 *data)
+{
+	unsigned int offset;
+	int ret;
+
+	if (thermal_version < 2 && index >= EC_TEMP_SENSOR_ENTRIES)
+		return -ENODEV;
+
+	if (index >= EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES)
+		return -ENODEV;
+
+	if (index < EC_TEMP_SENSOR_ENTRIES)
+		offset = EC_MEMMAP_TEMP_SENSOR + index;
+	else
+		offset = EC_MEMMAP_TEMP_SENSOR_B + index - EC_TEMP_SENSOR_ENTRIES;
+
+	ret = cros_ec->cmd_readmem(cros_ec, offset, 1, data);
+	if (ret < 0)
+		return ret;
+
+	if (*data == EC_TEMP_SENSOR_NOT_PRESENT ||
+	    *data == EC_TEMP_SENSOR_ERROR ||
+	    *data == EC_TEMP_SENSOR_NOT_POWERED ||
+	    *data == EC_TEMP_SENSOR_NOT_CALIBRATED)
+		return -ENODEV;
+
+	return 0;
+}
+
+static int cros_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+			      u32 attr, int channel, long *val)
+{
+	struct cros_ec_hwmon_priv *priv = dev_get_drvdata(dev);
+	u16 speed;
+	u8 temp;
+	int ret = -ENODATA;
+
+	if (type == hwmon_fan) {
+		ret = cros_ec_hwmon_read_fan_speed(priv->cros_ec, channel, &speed);
+		if (ret == 0)
+			*val = speed;
+	} else if (type == hwmon_temp) {
+		ret = cros_ec_hwmon_read_temp(priv->cros_ec, priv->thermal_version, channel, &temp);
+		if (ret == 0)
+			*val = kelvin_to_millicelsius((((long)temp) + EC_TEMP_SENSOR_OFFSET));
+	}
+
+	return ret;
+}
+
+static int cros_ec_hwmon_get_temp_sensor_info(struct cros_ec_device *cros_ec, u8 id,
+					      struct ec_response_temp_sensor_get_info *resp)
+{
+	int ret;
+	struct {
+		struct cros_ec_command msg;
+		union {
+			struct ec_params_temp_sensor_get_info req;
+			struct ec_response_temp_sensor_get_info resp;
+		} __packed data;
+	} __packed buf = {
+		.msg = {
+			.version = 0,
+			.command = EC_CMD_TEMP_SENSOR_GET_INFO,
+			.insize  = sizeof(buf.data.resp),
+			.outsize = sizeof(buf.data.req),
+		},
+		.data.req.id = id,
+	};
+
+	ret = cros_ec_cmd_xfer_status(cros_ec, &buf.msg);
+	if (ret < 0)
+		return ret;
+
+	*resp = buf.data.resp;
+	return 0;
+}
+
+static int cros_ec_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type,
+				     u32 attr, int channel, const char **str)
+{
+	struct cros_ec_hwmon_priv *priv = dev_get_drvdata(dev);
+	int ret = -ENODATA;
+
+	if (type == hwmon_temp && attr == hwmon_temp_label) {
+		*str = priv->temp_sensor_names[channel];
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static umode_t cros_ec_hwmon_is_visible(const void *data, enum hwmon_sensor_types type,
+					u32 attr, int channel)
+{
+	const struct cros_ec_hwmon_priv *priv = data;
+	u16 speed;
+
+	if (type == hwmon_fan) {
+		if (cros_ec_hwmon_read_fan_speed(priv->cros_ec, channel, &speed) == 0)
+			return 0444;
+	} else if (type == hwmon_temp) {
+		if (priv->temp_sensor_names[channel])
+			return 0444;
+	}
+
+	return 0;
+}
+
+static const struct hwmon_channel_info * const cros_ec_hwmon_info[] = {
+	HWMON_CHANNEL_INFO(fan,
+			   HWMON_F_INPUT,
+			   HWMON_F_INPUT,
+			   HWMON_F_INPUT,
+			   HWMON_F_INPUT),
+	HWMON_CHANNEL_INFO(temp,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL),
+	NULL
+};
+
+static const struct hwmon_ops cros_ec_hwmon_ops = {
+	.read = cros_ec_hwmon_read,
+	.read_string = cros_ec_hwmon_read_string,
+	.is_visible = cros_ec_hwmon_is_visible,
+};
+
+static const struct hwmon_chip_info cros_ec_hwmon_chip_info = {
+	.ops = &cros_ec_hwmon_ops,
+	.info = cros_ec_hwmon_info,
+};
+
+static int cros_ec_hwmon_probe_temp_sensors(struct device *dev, struct cros_ec_hwmon_priv *priv)
+{
+	struct ec_response_temp_sensor_get_info info;
+	size_t i;
+	u8 temp;
+	int ret;
+
+	ret = priv->cros_ec->cmd_readmem(priv->cros_ec, EC_MEMMAP_THERMAL_VERSION,
+					 1, &priv->thermal_version);
+	if (ret < 0)
+		return ret;
+
+	if (!priv->thermal_version)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(priv->temp_sensor_names); i++) {
+		if (cros_ec_hwmon_read_temp(priv->cros_ec, priv->thermal_version, i, &temp) != 0)
+			continue;
+
+		ret = cros_ec_hwmon_get_temp_sensor_info(priv->cros_ec, i, &info);
+		if (ret < 0)
+			continue;
+
+		priv->temp_sensor_names[i] = devm_kasprintf(dev, GFP_KERNEL, "%*s",
+							    (int)sizeof(info.sensor_name),
+							    info.sensor_name);
+	}
+
+	return 0;
+}
+
+static int cros_ec_hwmon_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent);
+	struct cros_ec_device *cros_ec = ec_dev->ec_dev;
+	struct cros_ec_hwmon_priv *priv;
+	struct device *hwmon_dev;
+	int ret;
+
+	BUILD_BUG_ON(ARRAY_SIZE(priv->temp_sensor_names) != 24);
+
+	/* Not every platform supports direct reads */
+	if (!cros_ec->cmd_readmem)
+		return -ENOTTY;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->cros_ec = cros_ec;
+
+	ret = cros_ec_hwmon_probe_temp_sensors(dev, priv);
+	if (ret < 0)
+		return ret;
+
+	hwmon_dev = devm_hwmon_device_register_with_info(dev, "cros_ec", priv,
+							 &cros_ec_hwmon_chip_info, NULL);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct platform_device_id cros_ec_hwmon_id[] = {
+	{ DRV_NAME, 0 },
+	{ }
+};
+
+static struct platform_driver cros_ec_hwmon_driver = {
+	.driver.name	= DRV_NAME,
+	.probe		= cros_ec_hwmon_probe,
+	.id_table	= cros_ec_hwmon_id,
+};
+module_platform_driver(cros_ec_hwmon_driver);
+
+MODULE_DEVICE_TABLE(platform, cros_ec_hwmon_id);
+MODULE_DESCRIPTION("ChromeOS EC Hardware Monitoring Driver");
+MODULE_AUTHOR("Thomas Weißschuh <linux@weissschuh.net");
+MODULE_LICENSE("GPL");

-- 
2.45.0


^ permalink raw reply related	[relevance 6%]

* 50% OFF din pret. linux-staging@lists.linux.dev
@ 2022-12-07 14:46  6% Publicitate digitala in mall-uri
  0 siblings, 0 replies; 200+ results
From: Publicitate digitala in mall-uri @ 2022-12-07 14:46 UTC (permalink / raw)
  To: linux-staging


[-- Attachment #1.1: Type: text/plain, Size: 4773 bytes --]





0771 303 303
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281778976&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=tel%3A0771303303&_ntm_sentIdx=1ed763dd-e12c-6e5c-a621-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397693&_ntm_usr=15532&_ntm_sig=9547361cdc8b84555016faee8f8520e9ab10876fdd3e05f6b9c54b87e306ef03)
office@ekogroup.ro
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281778976&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=mailto%3Aoffice%40ekogroup.ro&_ntm_sentIdx=1ed763dd-e12c-6e5c-a621-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397694&_ntm_usr=15532&_ntm_sig=2bb6d490043d555ad946e9a786a779f72e562872cc084972eb2e94f364ef5542)




Oferta digitala
DISCOUNT 50% din pretul chiriei TIMP DE 3 LUNI daca se semneaza si se achita 
contracte înaintea inceperii campaniilor!
  Primul totem la VERANDA mall dintr o serie de 5000 buc la nivel 
national(toate centrele comerciale din ROMANIA) în urmatorii 2 ani.   
Totemurile apartin companieiekogroup.ro 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281778976&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=http%3A%2F%2Fekogroup.ro%2F&_ntm_sentIdx=1ed763dd-e12c-6e5c-a621-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397695&_ntm_usr=15532&_ntm_sig=6bae3e2768df3c671ccf9d6e7ed0c8bc4a1ae020e61f0b26baf352087c57d602)
(nu suntem revanzatori de servicii)   Putem facilita vanzarea media kit-urilor 
indoor si outdoor în toate centrele comerciale la preturi avantajoase.   
Preturile sunt negociabile în functie de perioada.   Urmatoarele proiecte pana 
la decembrie 2022- martie 2023:   Mall Veranda: - 7 totem toate etajele - 4 tv 
uri 86 inch food court - exclusivitate vanzare media kit indoor-outdoor  Data 
incepere campanii: 20 decembrie 2022 https://youtube.com/shorts/N0_m1WJUrYE 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281778976&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=https%3A%2F%2Fyoutube.com%2Fshorts%2FN0_m1WJUrYE&_ntm_sentIdx=1ed763dd-e12c-6e5c-a621-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397696&_ntm_usr=15532&_ntm_sig=8ef41ca84ef3531f374c1b7b99a98eee21a3c99424ab656c4b2375ce856f1039)
  Cineplexx Baneasa: - videowall intrare cineplexx(vis a vis de Carturesti) 
https://drive.google.com/file/d/18tbAZ5KpOojmfyIK440n7wsSxF6k4W4m/view 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281778976&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=https%3A%2F%2Fdrive.google.com%2Ffile%2Fd%2F18tbAZ5KpOojmfyIK440n7wsSxF6k4W4m%2Fview&_ntm_sentIdx=1ed763dd-e12c-6e5c-a621-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397697&_ntm_usr=15532&_ntm_sig=06f1c4cbc791a6f27ee0763c86f087c1ee21026eb42953f92a59c52c52a50ef5)
- 2 totem 2300mm x 1230mm, 86 inch FOAYER Cineplexx Baneasa, PARTER - 1 totem 
subsol, vis a vis de sala VIP Data începere campanii: 1 martie 2023   Cineplexx 
TITAN: - 1 totem 98 inch intrare Cinplexx partea stânga - 2 totem 86 inch 
FOAYER langa stalpii de rezistenta - 1 totem 86 inch langa casele de 
bilete/popcorn - 2 totem 98 inch în proximitatea Foayerului salilor de cinema 
Data începere campanii: 15 ianuarie 2023   Reteaua KAUFLAND: - 1 totem 86 inch 
fata simpla la fiecare intrare/iesire KAUFLAND Bucuresti (Total avem 18 
locaÈ›ii, câte un totem pe fiecare locaÈ›ie) Data începere campanii: 1 martie 
2023 
 





Solicita oferta
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281778976&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=mailto%3Aoffice%40ekogroup.ro&_ntm_sentIdx=1ed763dd-e12c-6e5c-a621-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397694&_ntm_usr=15532&_ntm_sig=2bb6d490043d555ad946e9a786a779f72e562872cc084972eb2e94f364ef5542)



 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281778976&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=https%3A%2F%2Fwww.youtube.com%2Fshorts%2FN0_m1WJUrYE&_ntm_sentIdx=1ed763dd-e12c-6e5c-a621-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397698&_ntm_usr=15532&_ntm_sig=7770fc70fac9954e3a92ec6d9d154f6c3f187605c10942f783812c2fba34a581)




Solicita oferta
 
(https://tracking3.360nrs.net/tracker/?_ntm_cmp=558107&_ntm_cnt=281778976&_ntm_cty=2&_ntm_evt=3&_ntm_rdu=mailto%3Aoffice%40ekogroup.ro&_ntm_sentIdx=1ed763dd-e12c-6e5c-a621-46e19da0ac44&_ntm_snd=565323&_ntm_tur=131397694&_ntm_usr=15532&_ntm_sig=2bb6d490043d555ad946e9a786a779f72e562872cc084972eb2e94f364ef5542)




În conformitate cu prevederile Regulamentului (UE) 2016/679 din 27 aprilie 
2016 (GDPR), vă informăm că datele dumneavoastră cu caracter personal sunt 
prelucrate doar de către societatea noastră și au ca unic scop transmiterea de 
informații despre produsele și serviciile noastre. Vă puteți exercita 
drepturile de acces, de anulare.

Dezabonare  
(https://tracking3.360nrs.net/unsubscribe/mailing/15532/281778976/565323/9bf3e073f9/null/)



[-- Attachment #1.2: Type: text/html, Size: 30214 bytes --]

^ permalink raw reply	[relevance 6%]

* [PATCH v2 1/2] hwmon: add ChromeOS EC driver
  @ 2024-05-07 16:29  6% ` Thomas Weißschuh
  0 siblings, 0 replies; 200+ results
From: Thomas Weißschuh @ 2024-05-07 16:29 UTC (permalink / raw)
  To: Jean Delvare, Guenter Roeck, Benson Leung, Lee Jones
  Cc: Guenter Roeck, linux-kernel, linux-hwmon, chrome-platform,
	Dustin Howett, Mario Limonciello, Moritz Fischer,
	Thomas Weißschuh

The ChromeOS Embedded Controller exposes fan speed and temperature
readings.
Expose this data through the hwmon subsystem.

The driver is designed to be probed via the cros_ec mfd device.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 Documentation/hwmon/cros_ec_hwmon.rst |  26 ++++
 Documentation/hwmon/index.rst         |   1 +
 MAINTAINERS                           |   8 +
 drivers/hwmon/Kconfig                 |  11 ++
 drivers/hwmon/Makefile                |   1 +
 drivers/hwmon/cros_ec_hwmon.c         | 269 ++++++++++++++++++++++++++++++++++
 6 files changed, 316 insertions(+)

diff --git a/Documentation/hwmon/cros_ec_hwmon.rst b/Documentation/hwmon/cros_ec_hwmon.rst
new file mode 100644
index 000000000000..aeb88c79d11b
--- /dev/null
+++ b/Documentation/hwmon/cros_ec_hwmon.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Kernel driver cros_ec_hwmon
+===========================
+
+Supported chips:
+
+  * ChromeOS embedded controllers connected via LPC
+
+    Prefix: 'cros_ec'
+
+    Addresses scanned: -
+
+Author:
+
+  - Thomas Weißschuh <linux@weissschuh.net>
+
+Description
+-----------
+
+This driver implements support for hardware monitoring commands exposed by the
+ChromeOS embedded controller used in Chromebooks and other devices.
+
+The channel labels exposed via hwmon are retrieved from the EC itself.
+
+Fan and temperature readings are supported.
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 1ca7a4fe1f8f..355a83e66928 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -57,6 +57,7 @@ Hardware Monitoring Kernel Drivers
    coretemp
    corsair-cpro
    corsair-psu
+   cros_ec_hwmon
    da9052
    da9055
    dell-smm-hwmon
diff --git a/MAINTAINERS b/MAINTAINERS
index c23fda1aa1f0..aa5689169eca 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4988,6 +4988,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
 F:	sound/soc/codecs/cros_ec_codec.*
 
+CHROMEOS EC HARDWARE MONITORING
+M:	Thomas Weißschuh <thomas@weissschuh.net>
+L:	chrome-platform@lists.linux.dev
+L:	linux-hwmon@vger.kernel.org
+S:	Maintained
+F:	Documentation/hwmon/chros_ec_hwmon.rst
+F:	drivers/hwmon/cros_ec_hwmon.c
+
 CHROMEOS EC SUBDRIVERS
 M:	Benson Leung <bleung@chromium.org>
 R:	Guenter Roeck <groeck@chromium.org>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 83945397b6eb..c1284d42697f 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -506,6 +506,17 @@ config SENSORS_CORSAIR_PSU
 	  This driver can also be built as a module. If so, the module
 	  will be called corsair-psu.
 
+config SENSORS_CROS_EC
+	tristate "ChromeOS Embedded Controller sensors"
+	depends on MFD_CROS_EC_DEV
+	default MFD_CROS_EC_DEV
+	help
+	  If you say yes here you get support for ChromeOS Embedded Controller
+	  sensors.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called cros_ec_hwmon.
+
 config SENSORS_DRIVETEMP
 	tristate "Hard disk drives with temperature sensors"
 	depends on SCSI && ATA
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 5c31808f6378..8519a6b36c00 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_SENSORS_CHIPCAP2) += chipcap2.o
 obj-$(CONFIG_SENSORS_CORETEMP)	+= coretemp.o
 obj-$(CONFIG_SENSORS_CORSAIR_CPRO) += corsair-cpro.o
 obj-$(CONFIG_SENSORS_CORSAIR_PSU) += corsair-psu.o
+obj-$(CONFIG_SENSORS_CROS_EC)	+= cros_ec_hwmon.o
 obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
 obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o
 obj-$(CONFIG_SENSORS_DELL_SMM)	+= dell-smm-hwmon.o
diff --git a/drivers/hwmon/cros_ec_hwmon.c b/drivers/hwmon/cros_ec_hwmon.c
new file mode 100644
index 000000000000..d59d39df2ac4
--- /dev/null
+++ b/drivers/hwmon/cros_ec_hwmon.c
@@ -0,0 +1,269 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  ChromesOS EC driver for hwmon
+ *
+ *  Copyright (C) 2024 Thomas Weißschuh <linux@weissschuh.net>
+ */
+
+#include <linux/device.h>
+#include <linux/hwmon.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/cros_ec_commands.h>
+#include <linux/platform_data/cros_ec_proto.h>
+#include <linux/units.h>
+
+#define DRV_NAME	"cros-ec-hwmon"
+
+struct cros_ec_hwmon_priv {
+	struct cros_ec_device *cros_ec;
+	u8 thermal_version;
+	const char *temp_sensor_names[EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES];
+};
+
+static int cros_ec_hwmon_read_fan_speed(struct cros_ec_device *cros_ec, u8 index, u16 *speed)
+{
+	u16 data;
+	int ret;
+
+	ret = cros_ec->cmd_readmem(cros_ec, EC_MEMMAP_FAN + index * 2, 2, &data);
+	if (ret < 0)
+		return ret;
+
+	data = le16_to_cpu(data);
+
+	if (data == EC_FAN_SPEED_NOT_PRESENT)
+		return -ENODEV;
+
+	*speed = data;
+	return 0;
+}
+
+static int cros_ec_hwmon_read_temp(struct cros_ec_device *cros_ec, u8 thermal_version,
+				   u8 index, u8 *data)
+{
+	unsigned int offset;
+	int ret;
+
+	if (index < EC_TEMP_SENSOR_ENTRIES)
+		offset = EC_MEMMAP_TEMP_SENSOR + index;
+	else
+		offset = EC_MEMMAP_TEMP_SENSOR_B + index - EC_TEMP_SENSOR_ENTRIES;
+
+	ret = cros_ec->cmd_readmem(cros_ec, offset, 1, data);
+	if (ret < 0)
+		return ret;
+
+	if (*data == EC_TEMP_SENSOR_NOT_PRESENT ||
+	    *data == EC_TEMP_SENSOR_ERROR ||
+	    *data == EC_TEMP_SENSOR_NOT_POWERED ||
+	    *data == EC_TEMP_SENSOR_NOT_CALIBRATED)
+		return -ENODEV;
+
+	return 0;
+}
+
+static int cros_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+			      u32 attr, int channel, long *val)
+{
+	struct cros_ec_hwmon_priv *priv = dev_get_drvdata(dev);
+	int ret = -ENODATA;
+	u16 speed;
+	u8 temp;
+
+	if (type == hwmon_fan) {
+		ret = cros_ec_hwmon_read_fan_speed(priv->cros_ec, channel, &speed);
+		if (ret == 0)
+			*val = speed;
+	} else if (type == hwmon_temp) {
+		ret = cros_ec_hwmon_read_temp(priv->cros_ec, priv->thermal_version, channel, &temp);
+		if (ret == 0)
+			*val = kelvin_to_millicelsius((((long)temp) + EC_TEMP_SENSOR_OFFSET));
+	}
+
+	return ret;
+}
+
+static int cros_ec_hwmon_get_temp_sensor_info(struct cros_ec_device *cros_ec, u8 id,
+					      struct ec_response_temp_sensor_get_info *resp)
+{
+	int ret;
+	struct {
+		struct cros_ec_command msg;
+		union {
+			struct ec_params_temp_sensor_get_info req;
+			struct ec_response_temp_sensor_get_info resp;
+		} __packed data;
+	} __packed buf = {
+		.msg = {
+			.version = 0,
+			.command = EC_CMD_TEMP_SENSOR_GET_INFO,
+			.insize  = sizeof(buf.data.resp),
+			.outsize = sizeof(buf.data.req),
+		},
+		.data.req.id = id,
+	};
+
+	ret = cros_ec_cmd_xfer_status(cros_ec, &buf.msg);
+	if (ret < 0)
+		return ret;
+
+	*resp = buf.data.resp;
+	return 0;
+}
+
+static int cros_ec_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type,
+				     u32 attr, int channel, const char **str)
+{
+	struct cros_ec_hwmon_priv *priv = dev_get_drvdata(dev);
+
+	if (type == hwmon_temp && attr == hwmon_temp_label) {
+		*str = priv->temp_sensor_names[channel];
+		return 0;
+	}
+
+	return -ENODATA;
+}
+
+static umode_t cros_ec_hwmon_is_visible(const void *data, enum hwmon_sensor_types type,
+					u32 attr, int channel)
+{
+	const struct cros_ec_hwmon_priv *priv = data;
+	u16 speed;
+
+	if (type == hwmon_fan) {
+		if (cros_ec_hwmon_read_fan_speed(priv->cros_ec, channel, &speed) == 0)
+			return 0444;
+	} else if (type == hwmon_temp) {
+		if (priv->temp_sensor_names[channel])
+			return 0444;
+	}
+
+	return 0;
+}
+
+static const struct hwmon_channel_info * const cros_ec_hwmon_info[] = {
+	HWMON_CHANNEL_INFO(fan,
+			   HWMON_F_INPUT,
+			   HWMON_F_INPUT,
+			   HWMON_F_INPUT,
+			   HWMON_F_INPUT),
+	HWMON_CHANNEL_INFO(temp,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_LABEL),
+	NULL
+};
+
+static const struct hwmon_ops cros_ec_hwmon_ops = {
+	.read = cros_ec_hwmon_read,
+	.read_string = cros_ec_hwmon_read_string,
+	.is_visible = cros_ec_hwmon_is_visible,
+};
+
+static const struct hwmon_chip_info cros_ec_hwmon_chip_info = {
+	.ops = &cros_ec_hwmon_ops,
+	.info = cros_ec_hwmon_info,
+};
+
+static void cros_ec_hwmon_probe_temp_sensors(struct device *dev, struct cros_ec_hwmon_priv *priv)
+{
+	struct ec_response_temp_sensor_get_info info;
+	size_t candidates, i;
+	int ret;
+	u8 temp;
+
+	if (priv->thermal_version < 2)
+		candidates = EC_TEMP_SENSOR_ENTRIES;
+	else
+		candidates = ARRAY_SIZE(priv->temp_sensor_names);
+
+	for (i = 0; i < candidates; i++) {
+		if (cros_ec_hwmon_read_temp(priv->cros_ec, priv->thermal_version, i, &temp) != 0)
+			continue;
+
+		ret = cros_ec_hwmon_get_temp_sensor_info(priv->cros_ec, i, &info);
+		if (ret < 0)
+			continue;
+
+		priv->temp_sensor_names[i] = devm_kasprintf(dev, GFP_KERNEL, "%*s",
+							    (int)sizeof(info.sensor_name),
+							    info.sensor_name);
+	}
+}
+
+static int cros_ec_hwmon_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent);
+	struct cros_ec_device *cros_ec = ec_dev->ec_dev;
+	struct cros_ec_hwmon_priv *priv;
+	struct device *hwmon_dev;
+	int ret;
+
+	/* Not every platform supports direct reads */
+	if (!cros_ec->cmd_readmem)
+		return -ENODEV;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->cros_ec = cros_ec;
+
+	ret = priv->cros_ec->cmd_readmem(cros_ec, EC_MEMMAP_THERMAL_VERSION,
+					 1, &priv->thermal_version);
+	if (ret < 0)
+		return ret;
+
+	/* Covers both fan and temp sensors */
+	if (!priv->thermal_version)
+		return -ENODEV;
+
+	cros_ec_hwmon_probe_temp_sensors(dev, priv);
+
+	hwmon_dev = devm_hwmon_device_register_with_info(dev, "cros_ec", priv,
+							 &cros_ec_hwmon_chip_info, NULL);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct platform_device_id cros_ec_hwmon_id[] = {
+	{ DRV_NAME, 0 },
+	{ }
+};
+
+static struct platform_driver cros_ec_hwmon_driver = {
+	.driver.name	= DRV_NAME,
+	.probe		= cros_ec_hwmon_probe,
+	.id_table	= cros_ec_hwmon_id,
+};
+module_platform_driver(cros_ec_hwmon_driver);
+
+MODULE_DEVICE_TABLE(platform, cros_ec_hwmon_id);
+MODULE_DESCRIPTION("ChromeOS EC Hardware Monitoring Driver");
+MODULE_AUTHOR("Thomas Weißschuh <linux@weissschuh.net");
+MODULE_LICENSE("GPL");

-- 
2.45.0


^ permalink raw reply related	[relevance 6%]

* [PATCH] staging: r8188eu: Provide a TODO file for this driver
@ 2021-08-26  1:49  6% Fabio M. De Francesco
  0 siblings, 0 replies; 200+ results
From: Fabio M. De Francesco @ 2021-08-26  1:49 UTC (permalink / raw)
  To: gregkh, Larry.Finger, phil, linux-staging, linux-kernel
  Cc: Fabio M. De Francesco

Provide a TODO file that lists the tasks that should be carried out in
order to move this driver off drivers/staging.

Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
---

Thanks to Phillip Potter <phil@philpotter.co.uk> for for providing the first draft.

 drivers/staging/r8188eu/TODO | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 drivers/staging/r8188eu/TODO

diff --git a/drivers/staging/r8188eu/TODO b/drivers/staging/r8188eu/TODO
new file mode 100644
index 000000000000..4bccca69abac
--- /dev/null
+++ b/drivers/staging/r8188eu/TODO
@@ -0,0 +1,16 @@
+To-do list:
+
+* Correct the coding style according to Linux guidelines; please read the document
+at https://www.kernel.org/doc/html/latest/process/coding-style.html.
+* Remove unnecessary debugging/printing macros; for those that are still needed
+use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()).
+* Remove dead code such as unusued functions, variables, fields, etc..
+* Use in-kernel API and remove unnecessary wrappers where possible.
+* Remove the HAL layer and migrate its functionality into the relevant parts of
+the driver.
+* Switch to use LIB80211 (This work is currently in development by Larry Finger).
+* Switch to use MAC80211 (This work is currently in development by Larry Finger).
+
+Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
+Larry Finger <Larry.Finger@lwfinger.net>, Phillip Potter <phil@philpotter.co.uk>
+and CC linux-staging@lists.linux.dev, linux-kernel@vger.kernel.org.
-- 
2.32.0


^ permalink raw reply related	[relevance 6%]

* [PATCH] MAINTAINERS: Add drivers/firmware/google/ entry
@ 2022-10-22  0:26  6% Brian Norris
  0 siblings, 0 replies; 200+ results
From: Brian Norris @ 2022-10-22  0:26 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tzung-Bi Shih
  Cc: Brian Norris, Julius Werner, chrome-platform, Guenter Roeck,
	linux-kernel, Stephen Boyd

These are mostly used for Chrome platforms, so group it in with the same
mailing list, repo, and (one) committer.

Signed-off-by: Brian Norris <briannorris@chromium.org>
---
Per this conversation:
https://lore.kernel.org/lkml/af9c4bfd-d3fb-1c7a-fb38-0d8bbd507449@roeck-us.net/
Re: [PATCH] firmware: coreboot: Register bus in module init

I guess if this is fine with folks, Tzung-Bi might queue this up?

 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e9759eb08c57..ba57ef11c72f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8726,6 +8726,15 @@ S:	Supported
 F:	Documentation/networking/device_drivers/ethernet/google/gve.rst
 F:	drivers/net/ethernet/google
 
+GOOGLE FIRMWARE DRIVERS
+M:	Tzung-Bi Shih <tzungbi@google.com>
+R:	Brian Norris <briannorris@chromium.org>
+R:	Julius Werner <jwerner@chromium.org>
+L:	chrome-platform@lists.linux.dev
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git
+F:	drivers/firmware/google/
+
 GPD POCKET FAN DRIVER
 M:	Hans de Goede <hdegoede@redhat.com>
 L:	platform-driver-x86@vger.kernel.org
-- 
2.38.0.135.g90850a2211-goog


^ permalink raw reply related	[relevance 6%]

* [RFC PATCH 3/5] coco/tsm: Introduce a shared class device for TSMs
  @ 2024-01-30  9:24  6% ` Dan Williams
  0 siblings, 0 replies; 200+ results
From: Dan Williams @ 2024-01-30  9:24 UTC (permalink / raw)
  To: linux-coco
  Cc: Xiaoyao Li, Isaku Yamahata, Alexey Kardashevskiy, Wu Hao,
	Yilun Xu, Tom Lendacky, John Allen, linux-pci, gregkh

A "tsm" is a platform component that provides an API for securely
provisioning resources for a confidential guest (TVM) to consume. "TSM"
also happens to be the acronym the PCI specification uses to define the
platform agent that carries out device-security operations. That
platform capability is commonly called TEE I/O. It is this arrival of
TEE I/O platforms that requires the "tsm" concept to grow from a
low-level arch-specific detail of TVM instantiation, to a frontend
interface to mediate device setup and interact with general purpose
kernel subsystems outside of arch/ like the PCI core.

Provide a virtual (as in /sys/devices/virtual) class device interface to
front all of the aspects of a TSM and TEE I/O that are
cross-architecture common. This includes mechanisms like enumerating
available platform TEE I/O capabilities and provisioning connections
between the platform TSM and device DSMs.

It is expected to handle hardware TSMs, like AMD SEV-SNP and ARM CCA
where there is a physical TEE coprocessor device running firmware, as
well as software TSMs like Intel TDX and RISC-V COVE, where there is a
privileged software module loaded at runtime.

For now this is just the scaffolding for registering a TSM device and/or
TSM-specific attribute groups.

Cc: Xiaoyao Li <xiaoyao.li@intel.com>
Cc: Isaku Yamahata <isaku.yamahata@intel.com>
Cc: Alexey Kardashevskiy <aik@amd.com>
Cc: Wu Hao <hao.wu@intel.com>
Cc: Yilun Xu <yilun.xu@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: John Allen <john.allen@amd.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 Documentation/ABI/testing/sysfs-class-tsm |   12 +++
 drivers/virt/coco/tsm/Kconfig             |    7 ++
 drivers/virt/coco/tsm/Makefile            |    3 +
 drivers/virt/coco/tsm/class.c             |  100 +++++++++++++++++++++++++++++
 include/linux/tsm.h                       |    8 ++
 5 files changed, 130 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-tsm
 create mode 100644 drivers/virt/coco/tsm/class.c

diff --git a/Documentation/ABI/testing/sysfs-class-tsm b/Documentation/ABI/testing/sysfs-class-tsm
new file mode 100644
index 000000000000..304b50b53e65
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-tsm
@@ -0,0 +1,12 @@
+What:		/sys/class/tsm/tsm0/host
+Date:		January 2024
+Contact:	linux-coco@lists.linux.dev
+Description:
+		(RO) For hardware TSMs represented by a device in /sys/devices,
+		@host is a link to that device.
+		Links to hardware TSM sysfs ABIs:
+		- Documentation/ABI/testing/sysfs-driver-ccp
+
+		For software TSMs instantiated by a software module, @host is a
+		directory with attributes for that TSM, and those attributes are
+		documented below.
diff --git a/drivers/virt/coco/tsm/Kconfig b/drivers/virt/coco/tsm/Kconfig
index 69f04461c83e..595d86917462 100644
--- a/drivers/virt/coco/tsm/Kconfig
+++ b/drivers/virt/coco/tsm/Kconfig
@@ -5,3 +5,10 @@
 config TSM_REPORTS
 	select CONFIGFS_FS
 	tristate
+
+config ARCH_HAS_TSM
+	bool
+
+config TSM
+	depends on ARCH_HAS_TSM && SYSFS
+	tristate
diff --git a/drivers/virt/coco/tsm/Makefile b/drivers/virt/coco/tsm/Makefile
index b48504a3ccfd..f7561169faed 100644
--- a/drivers/virt/coco/tsm/Makefile
+++ b/drivers/virt/coco/tsm/Makefile
@@ -4,3 +4,6 @@
 
 obj-$(CONFIG_TSM_REPORTS) += tsm_reports.o
 tsm_reports-y := reports.o
+
+obj-$(CONFIG_TSM) += tsm.o
+tsm-y := class.o
diff --git a/drivers/virt/coco/tsm/class.c b/drivers/virt/coco/tsm/class.c
new file mode 100644
index 000000000000..a569fa6b09eb
--- /dev/null
+++ b/drivers/virt/coco/tsm/class.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2024 Intel Corporation. All rights reserved. */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/tsm.h>
+#include <linux/rwsem.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/cleanup.h>
+
+static DECLARE_RWSEM(tsm_core_rwsem);
+struct class *tsm_class;
+struct tsm_subsys {
+	struct device dev;
+	const struct tsm_info *info;
+} *tsm_subsys;
+
+int tsm_register(const struct tsm_info *info)
+{
+	struct device *dev __free(put_device) = NULL;
+	struct tsm_subsys *subsys;
+	int rc;
+
+	guard(rwsem_write)(&tsm_core_rwsem);
+	if (tsm_subsys) {
+		pr_warn("failed to register: \"%s\", \"%s\" already registered\n",
+			info->name, tsm_subsys->info->name);
+		return -EBUSY;
+	}
+
+	subsys = kzalloc(sizeof(*subsys), GFP_KERNEL);
+	if (!subsys)
+		return -ENOMEM;
+
+	subsys->info = info;
+	dev = &subsys->dev;
+	dev->class = tsm_class;
+	dev->groups = info->groups;
+	dev_set_name(dev, "tsm0");
+	rc = device_register(dev);
+	if (rc)
+		return rc;
+
+	if (info->host) {
+		rc = sysfs_create_link(&dev->kobj, &info->host->kobj, "host");
+		if (rc)
+			return rc;
+	}
+
+	/* don't auto-free @dev */
+	dev = NULL;
+	tsm_subsys = subsys;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(tsm_register);
+
+void tsm_unregister(const struct tsm_info *info)
+{
+	guard(rwsem_write)(&tsm_core_rwsem);
+	if (!tsm_subsys || info != tsm_subsys->info) {
+		pr_warn("failed to unregister: \"%s\", not currently registered\n",
+			info->name);
+		return;
+	}
+
+	if (info->host)
+		sysfs_remove_link(&tsm_subsys->dev.kobj, "host");
+	device_unregister(&tsm_subsys->dev);
+	tsm_subsys = NULL;
+}
+EXPORT_SYMBOL_GPL(tsm_unregister);
+
+static void tsm_release(struct device *dev)
+{
+	struct tsm_subsys *subsys = container_of(dev, typeof(*subsys), dev);
+
+	kfree(subsys);
+}
+
+static int __init tsm_init(void)
+{
+	tsm_class = class_create("tsm");
+	if (IS_ERR(tsm_class))
+		return PTR_ERR(tsm_class);
+
+	tsm_class->dev_release = tsm_release;
+	return 0;
+}
+module_init(tsm_init)
+
+static void __exit tsm_exit(void)
+{
+	class_destroy(tsm_class);
+}
+module_exit(tsm_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Trusted Security Module core device model");
diff --git a/include/linux/tsm.h b/include/linux/tsm.h
index 28753608fcf5..8cb8a661ba41 100644
--- a/include/linux/tsm.h
+++ b/include/linux/tsm.h
@@ -5,6 +5,12 @@
 #include <linux/sizes.h>
 #include <linux/types.h>
 
+struct tsm_info {
+	const char *name;
+	struct device *host;
+	const struct attribute_group **groups;
+};
+
 #define TSM_REPORT_INBLOB_MAX 64
 #define TSM_REPORT_OUTBLOB_MAX SZ_32K
 
@@ -66,4 +72,6 @@ extern const struct config_item_type tsm_report_extra_type;
 int tsm_report_register(const struct tsm_report_ops *ops, void *priv,
 			const struct config_item_type *type);
 int tsm_report_unregister(const struct tsm_report_ops *ops);
+int tsm_register(const struct tsm_info *info);
+void tsm_unregister(const struct tsm_info *info);
 #endif /* __TSM_H */


^ permalink raw reply related	[relevance 6%]

* Re: Is the data rate estimation for 5GHz channels overly pessimistic?
  @ 2023-10-14 17:42  6%   ` Simonas Kazlauskas
    1 sibling, 0 replies; 200+ results
From: Simonas Kazlauskas @ 2023-10-14 17:42 UTC (permalink / raw)
  To: James Prestwood; +Cc: iwd

Hey,

James Prestwood wrote:
>Hi Simonas,
>
>The signal strength for the 5GHz BSS's are very low. Anything below -80dbm is 
>_really_ bad. So it makes sense why IWD is choosing 2.4GHz instead. IWD's 
>estimation is based on data from the 802.11 spec, and capabilities advertised 
>by the APs.

The RSSI is an unfortunate combination of my walls being quite thick (and 
really good at attenuating 5GHz), the AP being right across said wall and, I 
believe, Ubiquiti’s automatic signal strength algorithm not picking the 
maximum transmit strength[^1] in order to avoid the sticky client problem.

[^1]: At the maximum allowed 20dBm transmit power the AverageRSSI is -72dBm.

Is -80dBm really that bad? In my experience even -85dBm felt quite serviceable 
in terms of speed and stability. Looking at Unifi’s own client diagnostics, I 
see that the connection to the machine in question does have an increased “TX 
Retries” metric at around 15%. But it is comparable to some other devices with 
RSSIs in the neighbourhood of -70dBm and retries still at around 13%, so I'm 
not quite sure if I should be paying much of my attention to that metric.

I unfortunately am not able to add more APs without tearing down the ceiling, 
and my experience with -80dBm really didn’t feel bad enough to justify maxing 
out the transmit power and thus incapacitating roaming elsewhere.

>Band steering should be done after authentication. APs shouldn't refuse 
>connections like that, otherwise what would be the point of having a 2.4GHz 
>network anyways if its impossible to connect to. Something else must be going 
>on here.

Got it, I’ll investigate the authentication failures further. Though any 
suggestions on what I should be looking at would be appreciated, as the only 
idea I have right now is to disable band steering and see if the 
authentication failures in the 2.4GHz band go away.

>This is probably because IWD doesn't take into account any of the newer 
>802.11ax IEs when estimating the data rate. So its estimation is based on VHT 
>and not the newest EHT rates.

Is taking into account the EHT rates something that *should* be implemented, 
or is this something that cannot be implemented (and thus this misestimation 
cannot be fixed?) I could dedicate some effort implementing this if its the 
former (though, again, any links to relevant resources or docs would be 
greatly appreciated to save me the effort looking for good ones myself, if you 
have any on hand.) If it is the latter, I would love to learn more about why 
that’s the case.

>Since the 2.4GHz BSS's are giving you such problems you could try a recently 
>added feature to disable the 2.4GHz band entirely. You can set 
>[Rank].BandModifier2_4Ghz=0.0.

Right. I don’t necessarily want to disable 2.4GHz entirely. The device in 
question is a laptop, and I use it sometimes in locations around my house 
where I don’t anticipate 5GHz channels to be a good choice at all. I could try 
fine-tuning for my experience by fiddling with these ranking modifiers, but my 
experience today isn’t *that* terrible that I wouldn’t be able to address it 
by other means.

>Also your BandModifier5Ghz setting has a typo, its using an uppercase 'H'. 
>Someone else got hit by this recently, we need to add support for both.

ACK

>Thanks,
>James

Thank you,
S.

^ permalink raw reply	[relevance 6%]

* + docs-admin-guide-mm-damon-usage-add-damon-debugfs-interface-deprecation-notice.patch added to mm-unstable branch
@ 2023-02-09 22:14  6% Andrew Morton
  0 siblings, 0 replies; 200+ results
From: Andrew Morton @ 2023-02-09 22:14 UTC (permalink / raw)
  To: mm-commits, corbet, sj, akpm


The patch titled
     Subject: Docs/admin-guide/mm/damon/usage: add DAMON debugfs interface deprecation notice
has been added to the -mm mm-unstable branch.  Its filename is
     docs-admin-guide-mm-damon-usage-add-damon-debugfs-interface-deprecation-notice.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/docs-admin-guide-mm-damon-usage-add-damon-debugfs-interface-deprecation-notice.patch

This patch will later appear in the mm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: SeongJae Park <sj@kernel.org>
Subject: Docs/admin-guide/mm/damon/usage: add DAMON debugfs interface deprecation notice
Date: Thu, 9 Feb 2023 19:20:07 +0000

Patch series "mm/damon: deprecate DAMON debugfs interface".

DAMON debugfs interface has announced to be deprecated after >v5.15 LTS
kernel is released.  And v6.1.y has been announced to be an LTS[1].

Though the announcement was there for a while, some people might not have
noticed that so far.  Also, some users could depend on it and have
problems at movng to the alternative (DAMON sysfs interface).

For such cases, keep the code and documents with warning messages and
contacts to ask helps for the deprecation.

[1] https://git.kernel.org/pub/scm/docs/kernel/website.git/commit/?id=332e9121320bc7461b2d3a79665caf153e51732c


This patch (of 3):

DAMON debugfs interface has announced to be deprecated after >v5.15 LTS
kernel is released.  And, v6.1.y has announced to be an LTS[1].

Though the announcement was there for a while, some people might not
noticed that so far.  Also, some users could depend on it and have
problems at  movng to the alternative (DAMON sysfs interface).

For such cases, note DAMON debugfs interface as deprecated, and contacts
to ask helps on the document.

[1] https://git.kernel.org/pub/scm/docs/kernel/website.git/commit/?id=332e9121320bc7461b2d3a79665caf153e51732c

Link: https://lkml.kernel.org/r/20230209192009.7885-1-sj@kernel.org
Link: https://lkml.kernel.org/r/20230209192009.7885-2-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 Documentation/admin-guide/mm/damon/usage.rst |   20 +++++++++++------
 1 file changed, 13 insertions(+), 7 deletions(-)

--- a/Documentation/admin-guide/mm/damon/usage.rst~docs-admin-guide-mm-damon-usage-add-damon-debugfs-interface-deprecation-notice
+++ a/Documentation/admin-guide/mm/damon/usage.rst
@@ -25,10 +25,12 @@ DAMON provides below interfaces for diff
   interface provides only simple :ref:`statistics <damos_stats>` for the
   monitoring results.  For detailed monitoring results, DAMON provides a
   :ref:`tracepoint <tracepoint>`.
-- *debugfs interface.*
+- *debugfs interface. (DEPRECATED!)*
   :ref:`This <debugfs_interface>` is almost identical to :ref:`sysfs interface
-  <sysfs_interface>`.  This will be removed after next LTS kernel is released,
-  so users should move to the :ref:`sysfs interface <sysfs_interface>`.
+  <sysfs_interface>`.  This is deprecated, so users should move to the
+  :ref:`sysfs interface <sysfs_interface>`.  If you depend on this and cannot
+  move, please report your usecase to damon@lists.linux.dev and
+  linux-mm@kvack.org.
 - *Kernel Space Programming Interface.*
   :doc:`This </mm/damon/api>` is for kernel space programmers.  Using this,
   users can utilize every feature of DAMON most flexibly and efficiently by
@@ -487,13 +489,17 @@ the files as above.  Above is only for a
 
 .. _debugfs_interface:
 
-debugfs Interface
-=================
+debugfs Interface (DEPRECATED!)
+===============================
 
 .. note::
 
-  DAMON debugfs interface will be removed after next LTS kernel is released, so
-  users should move to the :ref:`sysfs interface <sysfs_interface>`.
+  THIS IS DEPRECATED!
+
+  DAMON debugfs interface is deprecated, so users should move to the
+  :ref:`sysfs interface <sysfs_interface>`.  If you depend on this and cannot
+  move, please report your usecase to damon@lists.linux.dev and
+  linux-mm@kvack.org.
 
 DAMON exports eight files, ``attrs``, ``target_ids``, ``init_regions``,
 ``schemes``, ``monitor_on``, ``kdamond_pid``, ``mk_contexts`` and
_

Patches currently in -mm which might be from sj@kernel.org are

docs-admin-guide-mm-damon-usage-add-damon-debugfs-interface-deprecation-notice.patch
mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice.patch
mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message.patch


^ permalink raw reply	[relevance 6%]

* [PATCH 3/3] MAINTAINERS: Add the driver info of the ZHOUYI AI accelerator
  @ 2021-11-24  6:57  6% ` Cai Huoqing
  0 siblings, 0 replies; 200+ results
From: Cai Huoqing @ 2021-11-24  6:57 UTC (permalink / raw)
  To: caihuoqing
  Cc: Rob Herring, Greg Kroah-Hartman, devicetree, linux-kernel,
	linux-staging

ZHOUYI NPU is an AI accelerator chip which is integrated into ARM SOC,
such as Allwinner R329 SOC.
Add the driver info of ZHOUYI NPU to MAINTAINERS file.

Signed-off-by: Cai Huoqing <caihuoqing@baidu.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f32c7d733255..5d231aadaa3e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18163,6 +18163,12 @@ M:	Forest Bond <forest@alittletooquiet.net>
 S:	Odd Fixes
 F:	drivers/staging/vt665?/
 
+STAGING - ARM ZHOUYI NPU SUPPORT
+M:	Cai Huoqing <caihuoqing@baidu.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	drivers/staging/zynpu/
+
 STAGING SUBSYSTEM
 M:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:	linux-staging@lists.linux.dev
-- 
2.25.1


^ permalink raw reply related	[relevance 6%]

* [PATCH v2 3/3] MAINTAINERS: Add the driver info of the ZHOUYI AI accelerator
  @ 2021-11-24  8:46  6% ` Cai Huoqing
  0 siblings, 0 replies; 200+ results
From: Cai Huoqing @ 2021-11-24  8:46 UTC (permalink / raw)
  To: caihuoqing
  Cc: Rob Herring, Greg Kroah-Hartman, devicetree, linux-kernel,
	linux-staging

ZHOUYI NPU is an AI accelerator chip which is integrated into ARM SOC,
such as Allwinner R329 SOC.
Add the driver info of ZHOUYI NPU to MAINTAINERS file.

Signed-off-by: Cai Huoqing <caihuoqing@baidu.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f32c7d733255..5d231aadaa3e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18163,6 +18163,12 @@ M:	Forest Bond <forest@alittletooquiet.net>
 S:	Odd Fixes
 F:	drivers/staging/vt665?/
 
+STAGING - ARM ZHOUYI NPU SUPPORT
+M:	Cai Huoqing <caihuoqing@baidu.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	drivers/staging/zynpu/
+
 STAGING SUBSYSTEM
 M:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:	linux-staging@lists.linux.dev
-- 
2.25.1


^ permalink raw reply related	[relevance 6%]

Results 401-600 of ~10000   |  | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2023-11-03 21:34  6% [tip: x86/urgent] MAINTAINERS: Add Intel TDX entry tip-bot2 for Kirill A. Shutemov
2022-10-25  3:51  6% [PATCH v2 1/2] soc: loongson: add GUTS driver for loongson2 platforms Yinbo Zhu
2022-10-25  3:51  5% ` [PATCH v2 2/2] dt-bindings: soc: add loongson2 guts Yinbo Zhu
2023-11-03 21:26  6% [tip: x86/urgent] MAINTAINERS: Add Intel TDX entry tip-bot2 for Kirill A. Shutemov
2021-08-26  1:49  6% [PATCH] staging: r8188eu: Provide a TODO file for this driver Fabio M. De Francesco
2022-12-07 14:46  6% 50% OFF din pret. linux-staging@lists.linux.dev Publicitate digitala in mall-uri
2022-11-03  8:19  6% [PATCH v5 1/2] soc: loongson: add GUTS driver for loongson-2 platforms Yinbo Zhu
2022-11-03  8:19  5% ` [PATCH v5 2/2] dt-bindings: soc: add loongson-2 chipid Yinbo Zhu
2023-05-25 21:50  6% + docs-mm-damon-maintainer-profile-fix-typos-and-grammar-errors.patch added to mm-unstable branch Andrew Morton
2022-10-24 10:58  6% [PATCH v1 1/2] soc: loongson: add GUTS driver for loongson2 platforms Yinbo Zhu
2022-10-24 10:58  5% ` [PATCH v1 2/2] dt-bindings: soc: add loongson2 guts Yinbo Zhu
2023-07-24  8:12  6% [PATCH v2] MAINTAINERS: Add drivers/firmware/google/ entry Tzung-Bi Shih
2021-08-31 22:48  6% + documentation-llvm-update-irc-location.patch added to -mm tree akpm
2023-01-16 23:22  6% [f2fs-dev] [PATCH] MAINTAINERS: update fsverity git repo, list, and patchwork Eric Biggers
2023-01-16 23:22  6% ` Eric Biggers
2022-11-02  3:55  6% [PATCH v4 1/2] soc: loongson: add GUTS driver for loongson-2 platforms Yinbo Zhu
2022-11-02  3:55  5% ` [PATCH v4 2/2] dt-bindings: soc: add loongson-2 chipid Yinbo Zhu
2022-10-29  8:21  6% [PATCH v3 1/2] soc: loongson: add GUTS driver for loongson-2 platforms Yinbo Zhu
2022-10-29  8:21  5% ` [PATCH v3 2/2] dt-bindings: soc: add loongson-2 chipid Yinbo Zhu
2023-02-09 22:14  6% + docs-admin-guide-mm-damon-usage-add-damon-debugfs-interface-deprecation-notice.patch added to mm-unstable branch Andrew Morton
2022-10-22  0:26  6% [PATCH] MAINTAINERS: Add drivers/firmware/google/ entry Brian Norris
2023-06-22  8:34  5% [PATCH] scripts/quilt-mail: add email address for Conor Dooley Conor Dooley
2023-02-13 23:55  5% [merged mm-stable] mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice.patch removed from -mm tree Andrew Morton
2024-01-30  6:44  5% + mm-damon-dbgfs-implement-deprecation-notice-file.patch added to mm-unstable branch Andrew Morton
2024-01-12 18:19  5% add volatile flag to PV/LVs (for cache) to avoid degraded state on reboot lists.linux.dev
2022-10-25  2:04  5% [PATCH] MAINTAINERS: update Tzung-Bi's email address Tzung-Bi Shih
2024-05-14 16:51  5% [PATCH V2] MAINTAINERS: Change lingshan's email to kernel.org Zhu Lingshan
2023-02-03 10:00  5% [PATCH] MAINTAINERS: Add entry for the Loongson LS2X I2C driver Binbin Zhou
2023-08-23 18:44  5% [PATCH 1/1] MAINTAINERS: Add entries for NXP(Freescale) eDMA drivers Frank Li
2024-05-13 21:27  5% [PATCH] MAINTAINERS: Change lingshan's email to kernel.org Zhu Lingshan
2024-01-30  6:44  5% + mm-damon-rename-config_damon_dbgfs-to-damon_dbgfs_deprecated.patch added to mm-unstable branch Andrew Morton
2023-04-18 23:13  5% [PATCH net-next] MAINTAINERS: Resume MPTCP co-maintainer role Mat Martineau
2024-02-27 14:45  5% [PATCH] MAINTAINERS: apply maintainer role of Intel vDPA driver Zhu Lingshan
2022-04-07 17:57  5% [PATCH] MAINTAINERS: add self as clang reviewer Tom Rix
2021-06-08 15:39  5% [PATCH] README: fix typo Alyssa Ross
2022-12-07 14:47  5% 50% OFF din pret. nvdimm@lists.linux.dev Publicitate digitala in mall-uri
2022-07-02  0:46  5% [PATCH] MAINTAINERS: Add a general "kernel hardening" section Kees Cook
2023-07-09  0:30  5% [merged mm-hotfixes-stable] maintainers-update-ocfs2-devel-mailing-list-address.patch removed from -mm tree Andrew Morton
2022-04-13 21:00  5% [PATCH v2] bus: mhi: host: Add soc_reset sysfs Jeffrey Hugo
2023-11-11  0:49  5% [PATCH] MAINTAINERS: update virtio-fs mailing list address Stefan Hajnoczi
2023-02-03  6:35  5% [merged mm-stable] maintainers-damon-link-maintainer-profile-git-trees-and-website.patch removed from -mm tree Andrew Morton
2024-02-21 23:42  5% [folded-merged] mm-damon-dbgfs-implement-deprecation-notice-file-fix.patch " Andrew Morton
2022-04-18 17:18  5% [PATCH v3] bus: mhi: host: Add soc_reset sysfs Jeffrey Hugo
2023-08-24  3:04  5% [PATCH v2 1/1] MAINTAINERS: Add entries for NXP(Freescale) eDMA drivers Frank Li
2023-02-09 22:14  5% + mm-damon-kconfig-add-damon-debugfs-interface-deprecation-notice.patch added to mm-unstable branch Andrew Morton
2022-11-11  5:42  5% [PATCH v7 1/2] soc: loongson: add GUTS driver for loongson-2 platforms Yinbo Zhu
2022-11-11  5:42  5% ` [PATCH v7 2/2] dt-bindings: soc: add loongson-2 chipid Yinbo Zhu
2022-10-25  2:49  5% [PATCH v2] MAINTAINERS: update Tzung-Bi's email address Tzung-Bi Shih
2022-05-10  4:09  5% [merged mm-hotfixes-stable] maintainers-add-a-mailing-list-for-damon-development.patch removed from -mm tree Andrew Morton
2022-10-13 21:46  5% [PATCH] MAINTAINERS: git://github -> https://github.com for jonmason Palmer Dabbelt
2023-01-19 22:44  5% [PATCH mptcp-net] MAINTAINERS: Update MPTCP maintainer list and CREDITS Mat Martineau
2022-06-02 17:31  5% [PATCH] MAINTAINERS: add ARM/APPLE MACHINE mailing list Sven Peter
2022-06-02 17:31  5% ` Sven Peter
2022-11-04  2:48  5% [PATCH v6 1/2] soc: loongson: add GUTS driver for loongson-2 platforms Yinbo Zhu
2022-11-04  2:48  5% ` [PATCH v6 2/2] dt-bindings: soc: add loongson-2 chipid Yinbo Zhu
2021-06-02  6:33  5% [PATCH] REAMDE: Announce new mailing list Daniel Wagner
2023-08-31  9:57  5% [Cluster-devel] [PATCH 1/2] MAINTAINERS: Update gfs2 " Andrew Price
2023-08-31  9:57  5% ` Andrew Price
2023-08-31  9:57  5% ` [Cluster-devel] [PATCH 2/2] MAINTAINERS: Update dlm " Andrew Price
2023-08-31  9:57  5%   ` Andrew Price
2023-02-13 23:55  5% [merged mm-stable] mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message.patch removed from -mm tree Andrew Morton
2021-10-06  6:25  5% [PATCH] MAINTAINERS: Update the entry for MHI bus Manivannan Sadhasivam
2023-07-12 12:15  5% [PATCH] MAINTAINERS: Redo addition of ssm3515 to APPLE SOUND Martin Povišer
2023-11-14 13:57  5% [PATCH] Remove myself as maintainer of GFS2 Bob Peterson
2022-01-13 12:02  5% [PATCH v3] powerpc/papr_scm: Implement initial support for injecting smart errors Vaibhav Jain
2022-01-13 12:02  5% ` Vaibhav Jain
2022-05-03 18:07  5% [PATCH] MAINTAINERS: Add a mailing list for DAMON development SeongJae Park
2021-10-19 13:39  5% [PATCH v2] MAINTAINERS: Update the entry for MHI bus Manivannan Sadhasivam
2023-12-15 14:45  5% [PATCH mptcp-net] MAINTAINERS: add Geliang as reviewer for MPTCP Matthieu Baerts
2024-01-29 16:42  5% [PATCH 1/1] MAINTAINERS: add mail list for freescale imx ddr pmu driver Frank Li
2024-01-29 16:42  5% ` Frank Li
2024-02-05 15:48  5% [PATCH dlm/next] MAINTAINERS: update DLM git repository entry Alexander Aring
2022-02-08  3:12  5% [PATCH] MAINTAINERS: update cros_ec_codec maintainers Tzung-Bi Shih
2022-02-08  3:12  5% ` Tzung-Bi Shih
2023-04-18 18:57  5% [PATCH mptcp-next] MAINTAINERS: Resume MPTCP co-maintainer role Mat Martineau
2023-08-24 14:58  5% [PATCH v3 1/1] MAINTAINERS: Add entries for NXP(Freescale) eDMA drivers Frank Li
2023-01-10 22:41  5% + docs-mm-damon-add-a-maintainer-profile-for-damon.patch added to mm-unstable branch Andrew Morton
2022-04-10  4:39  5% [merged] maintainers-add-self-as-clang-reviewer.patch removed from -mm tree Andrew Morton
2023-10-04 14:32  5% [PATCH resent 1/1] MAINTAINERS: Add entries for NXP(Freescale) eDMA drivers Frank Li
2023-01-20 23:11  5% [PATCH net] MAINTAINERS: Update MPTCP maintainer list and CREDITS Mat Martineau
2023-07-02 17:36  5% + maintainers-update-ocfs2-devel-mailing-list-address.patch added to mm-hotfixes-unstable branch Andrew Morton
2022-04-07 20:51  5% + maintainers-add-self-as-clang-reviewer.patch added to -mm tree Andrew Morton
2024-01-17 10:24  5% [PATCH] drivers: watchdog: Add ChromeOS EC watchdog Lukasz Majczak
2022-01-24 20:22  5% [PATCH v4] powerpc/papr_scm: Implement initial support for injecting smart errors Vaibhav Jain
2022-01-24 20:22  5% ` Vaibhav Jain
2022-12-07 14:47  5% 50% OFF din pret. ntfs3@lists.linux.dev Publicitate digitala in mall-uri
2023-02-09 22:14  5% + mm-damon-dbgfs-print-damon-debugfs-interface-deprecation-message.patch added to mm-unstable branch Andrew Morton
2024-02-02 15:20  5% + mm-damon-dbgfs-implement-deprecation-notice-file-fix.patch " Andrew Morton
2023-07-16  9:46  4% [PATCH 1/6] docs/zh_TW: update admin-guide Hu Haowen
2024-02-22  0:02  4% [merged mm-stable] mm-damon-rename-config_damon_dbgfs-to-damon_dbgfs_deprecated.patch removed from -mm tree Andrew Morton
2023-06-13  7:58     [PATCH v13 0/2] spi: loongson: add bus driver for the loongson spi Yinbo Zhu
2023-06-13  7:58  5% ` [PATCH v13 1/2] spi: dt-bindings: add " Yinbo Zhu
2022-04-08 20:08     incoming Andrew Morton
2022-04-08 20:09  5% ` [patch 9/9] MAINTAINERS: add Tom as clang reviewer Andrew Morton
2022-04-08 20:09  5%   ` Andrew Morton
2021-11-24  6:57     [PATCH 0/3] staging: zynpu: Add driver support for ARM(China) ZHOUYI AI accelerator Cai Huoqing
2021-11-24  6:57  6% ` [PATCH 3/3] MAINTAINERS: Add the driver info of the " Cai Huoqing
2023-08-07 12:00     [PATCH v3 0/6] docs/zh_TW: update zh_TW's documentation from an ascensive aspect Hu Haowen
2023-08-07 12:00  4% ` [PATCH v3 1/6] docs/zh_TW: update admin-guide Hu Haowen
2022-08-19 12:54     [PATCH v2 0/4] ASoC platform driver for Apple MCA Martin Povišer
2022-08-19 12:54  5% ` [PATCH v2 3/4] ASoC: apple: mca: Start new platform driver Martin Povišer
2022-08-19 12:54  5%   ` Martin Povišer
2022-07-12 14:59     Linux 5.18.11 Greg Kroah-Hartman
2022-07-12 14:59  5% ` Greg Kroah-Hartman
2023-08-03  2:21     [PATCH v18 00/30] Add KVM LoongArch support Tianrui Zhao
2023-08-03  2:21  5% ` [PATCH v18 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2024-05-14 18:16     [PATCH v5 0/7] Linux RISC-V IOMMU Support Tomasz Jeznach
2024-05-14 18:16  5% ` [PATCH v5 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU Tomasz Jeznach
2024-05-14 18:16  5%   ` Tomasz Jeznach
2023-11-13 18:17     [PULL 0/5] Misc fixes for 2023-11-13 Philippe Mathieu-Daudé
2023-11-13 18:17  5% ` [PULL 5/5] MAINTAINERS: update virtio-fs mailing list address Philippe Mathieu-Daudé
2024-04-24  3:21     [PATCH v5 0/3] Add sysfs entry to EDL mode Qiang Yu
2024-04-24  3:21  5% ` [PATCH v5 1/3] bus: mhi: host: Add sysfs entry to force device to enter EDL Qiang Yu
2023-05-30  1:51     [PATCH v12 00/31] Add KVM LoongArch support Tianrui Zhao
2023-05-30  1:52  6% ` [PATCH v12 31/31] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2023-02-24 10:20     [PATCH RFC 0/4] Driver for Apple Z2 touchscreens Sasha Finkelstein via B4 Relay
2023-02-24 10:20  5% ` [PATCH RFC 1/4] dt-bindings: input: touchscreen: Add Z2 controller bindings Sasha Finkelstein
2023-02-24 10:20  5%   ` Sasha Finkelstein via B4 Relay
2023-02-24 10:20  5%   ` Sasha Finkelstein via B4 Relay
2022-08-08 22:41     [PATCH 0/3] ASoC platform driver for Apple MCA Martin Povišer
2022-08-08 22:41  5% ` [PATCH 2/3] ASoC: apple: mca: Start new platform driver Martin Povišer
2022-08-08 22:41  5%   ` Martin Povišer
2022-11-02 14:15     [PATCH v2 0/4] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein
2022-11-02 14:15  5% ` [PATCH v2 1/4] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2022-11-02 14:15  5%   ` Sasha Finkelstein
2023-04-03 14:19     [PATCH RESEND v9 0/5] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein via B4 Relay
2023-04-03 14:19  5% ` [PATCH RESEND v9 1/5] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2023-04-03 14:19  5%   ` Sasha Finkelstein via B4 Relay
2023-04-03 14:19  5%   ` Sasha Finkelstein via B4 Relay
2023-02-09 19:20     SeongJae Park
2023-02-09 19:20  5% ` [PATCH 2/3] mm/damon/Kconfig: add DAMON debugfs interface deprecation notice SeongJae Park
2023-02-09 19:20  5% ` [PATCH 3/3] mm/damon/dbgfs: print DAMON debugfs interface deprecation message SeongJae Park
2024-04-23 10:33     [PATCH v4 0/3] Add sysfs entry to EDL mode Qiang Yu
2024-04-23 10:33  5% ` [PATCH v4 1/3] bus: mhi: host: Add sysfs entry to force device to enter EDL Qiang Yu
2023-05-22  3:11     [PATCH v11 00/31] Add KVM LoongArch support Tianrui Zhao
2023-05-22  3:12  6% ` [PATCH v11 31/31] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2023-06-28  1:34     [PATCH 0/2] update ocfs2-devel mailing list addresses Anthony Iliopoulos
2023-06-28  1:34  5% ` [PATCH 1/2] MAINTAINERS: Update ocfs2-devel mailing list address Anthony Iliopoulos
2024-02-08 18:03     [PATCH net 0/7] mptcp: locking cleanup & misc. fixes Matthieu Baerts (NGI0)
2024-02-08 18:03  6% ` [PATCH net 7/7] MAINTAINERS: update Geliang's email address Matthieu Baerts (NGI0)
2024-04-15  8:49     [PATCH v3 0/3] Add sysfs entry to EDL mode Qiang Yu
2024-04-15  8:49  5% ` [PATCH v3 1/3] bus: mhi: host: Add sysfs entry to force device to enter EDL Qiang Yu
2023-01-25 15:10     [PATCH v7 0/5] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein
2023-01-25 15:10  5% ` [PATCH v7 1/5] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2023-01-25 15:10  5%   ` Sasha Finkelstein
2022-12-28  0:45     [PATCH 00/10] platform/chrome: cros_ec_typec: VDM support Prashant Malani
2022-12-28  0:45  5% ` [PATCH 06/10] platform/chrome: cros_ec_typec: Move structs to header Prashant Malani
2022-11-21 17:42     [PATCH RESEND v3 0/4] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein
2022-11-21 17:42  5% ` [PATCH RESEND v3 1/4] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2022-11-21 17:42  5%   ` Sasha Finkelstein
2021-10-16  6:57     [PATCH 0/3] MHI patches for v5.16 Manivannan Sadhasivam
2021-10-16  6:57  5% ` [PATCH 1/3] MAINTAINERS: Update the entry for MHI bus Manivannan Sadhasivam
2023-06-08  7:28     [PATCH v12 0/2] spi: loongson: add bus driver for the loongson spi Yinbo Zhu
2023-06-08  7:28  5% ` [PATCH v12 1/2] spi: add loongson spi bindings Yinbo Zhu
2023-06-29  7:55     [PATCH v16 00/30] Add KVM LoongArch support Tianrui Zhao
2023-06-29  7:55  5% ` [PATCH v16 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2023-08-14  7:43     [PATCH v2 0/5] tsm: Attestation Report ABI Dan Williams
2023-08-14  7:43  5% ` [PATCH v2 2/5] tsm: Introduce a shared ABI for attestation reports Dan Williams
2024-01-30  9:23     [RFC PATCH 0/5] Towards a shared TSM sysfs-ABI for Confidential Computing Dan Williams
2024-01-30  9:24  6% ` [RFC PATCH 3/5] coco/tsm: Introduce a shared class device for TSMs Dan Williams
2023-03-11  5:11     [PATCH v9 0/5] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein via B4 Relay
2023-03-11  5:11  5% ` [PATCH v9 1/5] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2023-03-11  5:11  5%   ` Sasha Finkelstein via B4 Relay
2023-03-11  5:11  5%   ` Sasha Finkelstein via B4 Relay
2023-08-24 16:39     [PATCH v2 0/3] arm: dts: imx93: add edmav3 support Frank Li
2023-08-24 16:39  5% ` [PATCH v2 1/1] MAINTAINERS: Add entries for NXP(Freescale) eDMA drivers Frank Li
2023-08-24 16:39  5%   ` Frank Li
2023-02-14 15:57     [PATCH RESEND 2 v7 0/5] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein via B4 Submission Endpoint
2023-02-14 15:57  5% ` [PATCH RESEND 2 v7 1/5] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2023-02-14 15:57  5%   ` Sasha Finkelstein via B4 Submission Endpoint
2023-02-14 15:57  5%   ` Sasha Finkelstein via B4 Submission Endpoint
2022-08-24 16:07     [PATCH v3 0/4] ASoC platform driver for Apple MCA Martin Povišer
2022-08-24 16:07  5% ` [PATCH v3 3/4] ASoC: apple: mca: Start new platform driver Martin Povišer
2022-08-24 16:07  5%   ` Martin Povišer
2024-05-07 13:57     [PATCH 0/2] ChromeOS Embedded controller hwmon driver Thomas Weißschuh
2024-05-07 13:57  6% ` [PATCH 1/2] hwmon: add ChromeOS EC driver Thomas Weißschuh
2023-02-10  4:48     [PATCH v2 0/3] mm/damon: deprecate DAMON debugfs interface SeongJae Park
2023-02-10  4:48  5% ` [PATCH v2 2/3] mm/damon/Kconfig: add DAMON debugfs interface deprecation notice SeongJae Park
2023-02-10  4:48  5% ` [PATCH v2 3/3] mm/damon/dbgfs: print DAMON debugfs interface deprecation message SeongJae Park
2022-11-11 17:33     [PATCH v3 0/4] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein
2022-11-11 17:33  5% ` [PATCH v3 1/4] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2022-11-11 17:33  5%   ` Sasha Finkelstein
2023-09-27  3:09     [PATCH v22 00/25] Add KVM LoongArch support Tianrui Zhao
2023-09-27  3:09  5% ` [PATCH v22 25/25] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2023-10-14  9:23     Is the data rate estimation for 5GHz channels overly pessimistic? Simonas Kazlauskas
2023-10-14 16:02     ` James Prestwood
2023-10-14 17:42  6%   ` Simonas Kazlauskas
2023-10-14 17:36       ` Denis Kenzior
2023-10-14 17:45         ` Simonas Kazlauskas
2023-10-14 18:07           ` Denis Kenzior
2023-10-15 19:40  6%         ` Simonas Kazlauskas
2023-10-16 11:35               ` James Prestwood
2023-10-16 12:38                 ` James Prestwood
2023-10-16 19:12                   ` Denis Kenzior
2023-10-16 20:20                     ` Simonas Kazlauskas
2023-10-21 23:23  5%                   ` Simonas Kazlauskas
2022-09-23 15:42     [PATCH v1 0/3] Improve Landlock help Mickaël Salaün
2022-09-23 15:42     ` [PATCH v1 2/3] landlock: Slightly improve documentation and fix spelling Mickaël Salaün
2022-09-24 13:29  5%   ` Bagas Sanjaya
2022-12-09 11:13     [PATCH v4 0/4] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein
2022-12-09 11:13  5% ` [PATCH v4 1/4] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2022-12-09 11:13  5%   ` Sasha Finkelstein
2021-11-24  8:46     [PATCH v2 0/3] staging: zynpu: Add driver support for ARM(China) ZHOUYI AI accelerator Cai Huoqing
2021-11-24  8:46  6% ` [PATCH v2 3/3] MAINTAINERS: Add the driver info of the " Cai Huoqing
2024-05-07 16:29     [PATCH v2 0/2] ChromeOS Embedded controller hwmon driver Thomas Weißschuh
2024-05-07 16:29  6% ` [PATCH v2 1/2] hwmon: add ChromeOS EC driver Thomas Weißschuh
2023-08-17 12:59     [PATCH v19 00/30] Add KVM LoongArch support Tianrui Zhao
2023-08-17 12:59  5% ` [PATCH v19 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2023-07-20  6:27     [PATCH v17 00/30] Add KVM LoongArch support Tianrui Zhao
2023-07-20  6:28  5% ` [PATCH v17 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2023-12-26 12:10     [PATCH net 0/2] mptcp: new reviewer and prevent a warning Matthieu Baerts
2023-12-26 12:10  5% ` [PATCH net 1/2] MAINTAINERS: add Geliang as reviewer for MPTCP Matthieu Baerts
2023-06-09  9:04     [PATCH v13 00/30] Add KVM LoongArch support Tianrui Zhao
2023-06-09  9:05  6% ` [PATCH v13 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2024-04-30 20:01     [PATCH v3 0/7] Linux RISC-V IOMMU Support Tomasz Jeznach
2024-04-30 20:01  5% ` [PATCH v3 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU Tomasz Jeznach
2024-04-30 20:01  5%   ` Tomasz Jeznach
2022-12-21 21:06     [PATCH v5 0/4] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein
2022-12-21 21:06  5% ` [PATCH v5 1/4] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2022-12-21 21:06  5%   ` Sasha Finkelstein
2023-12-18  7:38     [RFC PATCH v3 0/7] Add virtio_rtc module and related changes Peter Hilber
2023-12-18  7:38  5% ` [RFC PATCH v3 4/7] virtio_rtc: Add module and driver core Peter Hilber
2023-12-18  7:38  5%   ` [virtio-dev] " Peter Hilber
2023-12-18  7:38  5%   ` Peter Hilber
2024-04-18 16:32     [PATCH v2 0/7] Linux RISC-V IOMMU Support Tomasz Jeznach
2024-04-18 16:32  5% ` [PATCH v2 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU Tomasz Jeznach
2024-04-18 16:32  5%   ` Tomasz Jeznach
2023-01-06 13:58     [PATCH v6 0/5] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein
2023-01-06 13:58  5% ` [PATCH v6 1/5] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2023-01-06 13:58  5%   ` Sasha Finkelstein
2023-06-26  8:47     [PATCH v15 00/30] Add KVM LoongArch support Tianrui Zhao
2023-06-26  8:47  5% ` [PATCH v15 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2023-09-15  1:49     [PATCH v21 00/29] Add KVM LoongArch support Tianrui Zhao
2023-09-15  1:49  5% ` [PATCH v21 29/29] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2023-08-31  8:29     [PATCH v20 00/30] Add KVM LoongArch support Tianrui Zhao
2023-08-31  8:30  5% ` [PATCH v20 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2023-12-21 16:37     [xenomai-images][PATCH v2 0/7] Add evl support to xenomai-images Clara Kowalsky
2023-12-21 16:37  5% ` [xenomai-images][PATCH v2 4/7] xenomai-4: Add evl userspace Clara Kowalsky
2024-02-13  0:11     [PATCH v4 0/3] virtiofs: export filesystem tags through sysfs Stefan Hajnoczi
2024-02-13  0:11  5% ` [PATCH v4 2/3] " Stefan Hajnoczi
2023-06-19  8:32     [PATCH v14 00/30] Add KVM LoongArch support Tianrui Zhao
2023-06-19  8:32  5% ` [PATCH v14 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2023-03-11  5:06     [PATCH v9 0/5] Hi, Sasha Finkelstein via B4 Relay
2023-03-11  5:06  5% ` [PATCH v9 1/5] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2023-03-11  5:06  5%   ` Sasha Finkelstein via B4 Relay
2023-03-11  5:06  5%   ` Sasha Finkelstein via B4 Relay
2022-07-12  0:08     [PATCH 00/25] [PULL REQUEST] Intel IOMMU updates for Linux v5.20 Lu Baolu
2022-07-12  0:08  6% ` [PATCH 07/25] iommu/vt-d: Move include/linux/intel-iommu.h under iommu Lu Baolu
2023-03-10 18:44     [PATCH v8 0/5] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein via B4 Relay
2023-03-10 18:44  5% ` [PATCH v8 1/5] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2023-03-10 18:44  5%   ` Sasha Finkelstein via B4 Relay
2023-03-10 18:44  5%   ` Sasha Finkelstein via B4 Relay
2024-02-09 12:18     [PATCH v3 0/3] virtiofs: export filesystem tags through sysfs Stefan Hajnoczi
2024-02-09 12:18  5% ` [PATCH v3 2/3] " Stefan Hajnoczi
2023-01-14 13:25     [PATCH v7 0/5] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein
2023-01-14 13:25  5% ` [PATCH v7 1/5] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2023-01-14 13:25  5%   ` Sasha Finkelstein
2021-07-12  6:00     [PATCH 5.13 000/800] 5.13.2-rc1 review Greg Kroah-Hartman
2021-07-12  6:12  6% ` [PATCH 5.13 755/800] powerpc/papr_scm: Make perf_stats invisible if perf-stats unavailable Greg Kroah-Hartman
2024-02-08 19:32     [PATCH v2 0/3] virtiofs: export filesystem tags through sysfs Stefan Hajnoczi
2024-02-08 19:32  5% ` [PATCH v2 2/3] " Stefan Hajnoczi
2024-04-12  8:51     [RFC PATCH v2 0/6] Towards a shared TSM sysfs-ABI for Confidential Computing Dan Williams
2024-04-12  8:52  5% ` [RFC PATCH v2 4/6] coco/tsm: Introduce a class device for TEE Security Managers Dan Williams
2024-04-12  8:51  5% ` [RFC PATCH v2 2/6] coco/guest: Move shared guest CC infrastructure to drivers/virt/coco/guest/ Dan Williams
2022-10-28 16:52     [PATCH 0/4] PWM and keyboard backlight driver for ARM Macs Sasha Finkelstein
2022-10-28 16:52  5% ` [PATCH 1/4] dt-bindings: pwm: Add Apple PWM controller Sasha Finkelstein
2022-10-28 16:52  5%   ` Sasha Finkelstein
2023-07-28  7:49     [PATCH v5 0/2] soc: loongson2_pm: add power management support Yinbo Zhu
2023-07-28  8:43     ` Conor Dooley
2023-07-28  9:48       ` Huacai Chen
2023-07-28 10:18         ` Conor Dooley
2023-07-31 14:13           ` Huacai Chen
2023-07-31 19:28             ` Arnd Bergmann
2023-08-01  8:16  5%           ` Conor Dooley
2024-04-19 12:19     [PATCH 01/19] liba52: remove the recipe Alexander Kanavin
2024-04-19 12:19  5% ` [PATCH 19/19] connman: submit 0002-resolve-musl-does-not-implement-res_ninit.patch upstream Alexander Kanavin
2024-01-30  1:35     [PATCH 0/9] mm/damon: make DAMON debugfs interface deprecation unignorable SeongJae Park
2024-01-30  1:35  6% ` [PATCH 2/9] mm/damon: rename CONFIG_DAMON_DBGFS to DAMON_DBGFS_DEPRECATED SeongJae Park
2024-01-30  1:35  6% ` [PATCH 3/9] mm/damon/dbgfs: implement deprecation notice file SeongJae Park
2024-01-28 21:25     [RFC PATCH v2 0/4] tsm: Runtime measurement registers ABI Samuel Ortiz
2024-01-28 21:25  5% ` [RFC PATCH v2 4/4] tsm: Allow for extending and reading configured RTMRs Samuel Ortiz
2023-06-09  9:08     [PATCH v13 00/30] Add KVM LoongArch support Tianrui Zhao
2023-06-09  9:08  6% ` [PATCH v13 30/30] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2024-05-03 16:12     [PATCH v4 0/7] Linux RISC-V IOMMU Support Tomasz Jeznach
2024-05-03 16:12  5% ` [PATCH v4 1/7] dt-bindings: iommu: riscv: Add bindings for RISC-V IOMMU Tomasz Jeznach
2024-05-03 16:12  5%   ` Tomasz Jeznach

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.