* [PATCH v5 1/2] dt-bindings: clock: Add Amlogic A9 peripherals clock controller
From: Jian Hu via B4 Relay @ 2026-06-30 2:36 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
In-Reply-To: <20260630-a9_peripherals-v5-0-bc4019730354@amlogic.com>
From: Jian Hu <jian.hu@amlogic.com>
Add the peripherals clock controller dt-bindings for the Amlogic A9
SoC family.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
.../clock/amlogic,a9-peripherals-clkc.yaml | 164 ++++++++++
.../clock/amlogic,a9-peripherals-clkc.h | 351 +++++++++++++++++++++
2 files changed, 515 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml
new file mode 100644
index 000000000000..f0aef005ecf3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml
@@ -0,0 +1,164 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2026 Amlogic, Inc. All rights reserved
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a9-peripherals-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A9 Series Peripherals Clock Controller
+
+maintainers:
+ - Neil Armstrong <neil.armstrong@linaro.org>
+ - Jerome Brunet <jbrunet@baylibre.com>
+ - Jian Hu <jian.hu@amlogic.com>
+ - Xianwei Zhao <xianwei.zhao@amlogic.com>
+
+properties:
+ compatible:
+ const: amlogic,a9-peripherals-clkc
+
+ reg:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+
+ clocks:
+ minItems: 27
+ items:
+ - description: input oscillator
+ - description: input fclk div 2
+ - description: input fclk div 3
+ - description: input fclk div 4
+ - description: input fclk div 5
+ - description: input fclk div 7
+ - description: input fclk div 2p5
+ - description: input sys clk
+ - description: input gp1 pll
+ - description: input gp2 pll
+ - description: input sys pll div 16
+ - description: input cpu clk div 16
+ - description: input a78 clk div 16
+ - description: input dsu clk div 16
+ - description: input rtc clk
+ - description: input gp0 pll
+ - description: input hifi0 pll
+ - description: input hifi1 pll
+ - description: input mclk0 pll
+ - description: input mclk1 pll
+ - description: input video1 pll
+ - description: input video2 pll
+ - description: input hdmi out2 clk
+ - description: input hdmi pixel clk
+ - description: input pixel0 pll
+ - description: input pixel1 pll
+ - description: input ddr pll test clk
+ - description: external input rmii oscillator (optional)
+
+ clock-names:
+ minItems: 27
+ items:
+ - const: xtal
+ - const: fdiv2
+ - const: fdiv3
+ - const: fdiv4
+ - const: fdiv5
+ - const: fdiv7
+ - const: fdiv2p5
+ - const: sys
+ - const: gp1
+ - const: gp2
+ - const: sysplldiv16
+ - const: cpudiv16
+ - const: a78div16
+ - const: dsudiv16
+ - const: rtc
+ - const: gp0
+ - const: hifi0
+ - const: hifi1
+ - const: mclk0
+ - const: mclk1
+ - const: vid1
+ - const: vid2
+ - const: hdmiout2
+ - const: hdmipix
+ - const: pix0
+ - const: pix1
+ - const: ddr_test
+ - const: ext_rmii
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ clock-controller@200 {
+ compatible = "amlogic,a9-peripherals-clkc";
+ reg = <0x0 0x200 0x0 0x2f8>;
+ #clock-cells = <1>;
+ clocks = <&xtal>,
+ <&scmi_clk 10>,
+ <&scmi_clk 12>,
+ <&scmi_clk 14>,
+ <&scmi_clk 16>,
+ <&scmi_clk 18>,
+ <&scmi_clk 20>,
+ <&scmi_clk 21>,
+ <&scmi_clk 33>,
+ <&scmi_clk 34>,
+ <&scmi_clk 35>,
+ <&scmi_clk 36>,
+ <&scmi_clk 37>,
+ <&scmi_clk 38>,
+ <&scmi_clk 40>,
+ <&gp0 3>,
+ <&hifi0 3>,
+ <&hifi1 3>,
+ <&mclk0 3>,
+ <&mclk1 3>,
+ <&vid1>,
+ <&vid2>,
+ <&hdmitx 10>,
+ <&hdmitx 11>,
+ <&pix0>,
+ <&pix1>,
+ <&ddr 3>;
+ clock-names = "xtal",
+ "fdiv2",
+ "fdiv3",
+ "fdiv4",
+ "fdiv5",
+ "fdiv7",
+ "fdiv2p5",
+ "sys",
+ "gp1",
+ "gp2",
+ "sysplldiv16",
+ "cpudiv16",
+ "a78div16",
+ "dsudiv16",
+ "rtc",
+ "gp0",
+ "hifi0",
+ "hifi1",
+ "mclk0",
+ "mclk1",
+ "vid1",
+ "vid2",
+ "hdmiout2",
+ "hdmipix",
+ "pix0",
+ "pix1",
+ "ddr_test";
+ };
+ };
diff --git a/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h
new file mode 100644
index 000000000000..09487a414197
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h
@@ -0,0 +1,351 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2026 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __AMLOGIC_A9_PERIPHERALS_CLKC_H
+#define __AMLOGIC_A9_PERIPHERALS_CLKC_H
+
+#define CLKID_SYS_AM_AXI 0
+#define CLKID_SYS_DOS 1
+#define CLKID_SYS_MIPI_DSI0 2
+#define CLKID_SYS_ETH_PHY 3
+#define CLKID_SYS_AMFC 4
+#define CLKID_SYS_MALI 5
+#define CLKID_SYS_NNA 6
+#define CLKID_SYS_ETH_AXI 7
+#define CLKID_SYS_DP_APB 8
+#define CLKID_SYS_EDPTX_APB 9
+#define CLKID_SYS_U3HSG 10
+#define CLKID_SYS_AUCPU 11
+#define CLKID_SYS_GLB 12
+#define CLKID_SYS_COMBO_DPHY_APB 13
+#define CLKID_SYS_HDMIRX_APB 14
+#define CLKID_SYS_HDMIRX_PCLK 15
+#define CLKID_SYS_MIPI_DSI0_PHY 16
+#define CLKID_SYS_CAN0 17
+#define CLKID_SYS_CAN1 18
+#define CLKID_SYS_SD_EMMC_A 19
+#define CLKID_SYS_SD_EMMC_B 20
+#define CLKID_SYS_SD_EMMC_C 21
+#define CLKID_SYS_SC 22
+#define CLKID_SYS_ACODEC 23
+#define CLKID_SYS_MIPI_ISP 24
+#define CLKID_SYS_MSR 25
+#define CLKID_SYS_AUDIO 26
+#define CLKID_SYS_MIPI_DSI1 27
+#define CLKID_SYS_MIPI_DSI1_PHY 28
+#define CLKID_SYS_ETH 29
+#define CLKID_SYS_ETH_1G_MAC 30
+#define CLKID_SYS_UART_A 31
+#define CLKID_SYS_UART_F 32
+#define CLKID_SYS_TS_A55 33
+#define CLKID_SYS_ETH_1G_AXI 34
+#define CLKID_SYS_TS_DOS 35
+#define CLKID_SYS_U3DRD_B 36
+#define CLKID_SYS_TS_CORE 37
+#define CLKID_SYS_TS_PLL 38
+#define CLKID_SYS_CSI_DIG_CLKIN 39
+#define CLKID_SYS_CVE 40
+#define CLKID_SYS_GE2D 41
+#define CLKID_SYS_SPISG 42
+#define CLKID_SYS_U2H 43
+#define CLKID_SYS_PCIE_MAC_A 44
+#define CLKID_SYS_U3DRD_A 45
+#define CLKID_SYS_U2DRD 46
+#define CLKID_SYS_PCIE_PHY 47
+#define CLKID_SYS_PCIE_MAC_B 48
+#define CLKID_SYS_PERIPH 49
+#define CLKID_SYS_PIO 50
+#define CLKID_SYS_I3C 51
+#define CLKID_SYS_I2C_M_E 52
+#define CLKID_SYS_I2C_M_F 53
+#define CLKID_SYS_HDMITX_APB 54
+#define CLKID_SYS_I2C_M_I 55
+#define CLKID_SYS_I2C_M_G 56
+#define CLKID_SYS_I2C_M_H 57
+#define CLKID_SYS_HDMI20_AES 58
+#define CLKID_SYS_CSI2_HOST 59
+#define CLKID_SYS_CSI2_ADAPT 60
+#define CLKID_SYS_DSPA 61
+#define CLKID_SYS_PP_DMA 62
+#define CLKID_SYS_PP_WRAPPER 63
+#define CLKID_SYS_VPU_INTR 64
+#define CLKID_SYS_CSI2_PHY 65
+#define CLKID_SYS_SARADC 66
+#define CLKID_SYS_PWM_J 67
+#define CLKID_SYS_PWM_I 68
+#define CLKID_SYS_PWM_H 69
+#define CLKID_SYS_PWM_N 70
+#define CLKID_SYS_PWM_M 71
+#define CLKID_SYS_PWM_L 72
+#define CLKID_SYS_PWM_K 73
+#define CLKID_SD_EMMC_A_SEL 74
+#define CLKID_SD_EMMC_A_DIV 75
+#define CLKID_SD_EMMC_A 76
+#define CLKID_SD_EMMC_B_SEL 77
+#define CLKID_SD_EMMC_B_DIV 78
+#define CLKID_SD_EMMC_B 79
+#define CLKID_SD_EMMC_C_SEL 80
+#define CLKID_SD_EMMC_C_DIV 81
+#define CLKID_SD_EMMC_C 82
+#define CLKID_PWM_H_SEL 83
+#define CLKID_PWM_H_DIV 84
+#define CLKID_PWM_H 85
+#define CLKID_PWM_I_SEL 86
+#define CLKID_PWM_I_DIV 87
+#define CLKID_PWM_I 88
+#define CLKID_PWM_J_SEL 89
+#define CLKID_PWM_J_DIV 90
+#define CLKID_PWM_J 91
+#define CLKID_PWM_K_SEL 92
+#define CLKID_PWM_K_DIV 93
+#define CLKID_PWM_K 94
+#define CLKID_PWM_L_SEL 95
+#define CLKID_PWM_L_DIV 96
+#define CLKID_PWM_L 97
+#define CLKID_PWM_M_SEL 98
+#define CLKID_PWM_M_DIV 99
+#define CLKID_PWM_M 100
+#define CLKID_PWM_N_SEL 101
+#define CLKID_PWM_N_DIV 102
+#define CLKID_PWM_N 103
+#define CLKID_SPISG0_SEL 104
+#define CLKID_SPISG0_DIV 105
+#define CLKID_SPISG0 106
+#define CLKID_SPISG1_SEL 107
+#define CLKID_SPISG1_DIV 108
+#define CLKID_SPISG1 109
+#define CLKID_SPISG2_SEL 110
+#define CLKID_SPISG2_DIV 111
+#define CLKID_SPISG2 112
+#define CLKID_SARADC_SEL 113
+#define CLKID_SARADC_DIV 114
+#define CLKID_SARADC 115
+#define CLKID_AMFC_SEL 116
+#define CLKID_AMFC_DIV 117
+#define CLKID_AMFC 118
+#define CLKID_NNA_SEL 119
+#define CLKID_NNA_DIV 120
+#define CLKID_NNA 121
+#define CLKID_USB_250M_SEL 122
+#define CLKID_USB_250M_DIV 123
+#define CLKID_USB_250M 124
+#define CLKID_USB_48M_PRE_SEL 125
+#define CLKID_USB_48M_PRE_DIV 126
+#define CLKID_USB_48M_PRE 127
+#define CLKID_PCIE0_TL_SEL 128
+#define CLKID_PCIE0_TL_DIV 129
+#define CLKID_PCIE0_TL 130
+#define CLKID_PCIE1_TL_SEL 131
+#define CLKID_PCIE1_TL_DIV 132
+#define CLKID_PCIE1_TL 133
+#define CLKID_CMPR_SEL 134
+#define CLKID_CMPR_DIV 135
+#define CLKID_CMPR 136
+#define CLKID_DEWARPA_SEL 137
+#define CLKID_DEWARPA_DIV 138
+#define CLKID_DEWARPA 139
+#define CLKID_SC_PRE_SEL 140
+#define CLKID_SC_PRE_DIV 141
+#define CLKID_SC_PRE 142
+#define CLKID_SC 143
+#define CLKID_DPTX_APB2_SEL 144
+#define CLKID_DPTX_APB2_DIV 145
+#define CLKID_DPTX_APB2 146
+#define CLKID_DPTX_AUD_SEL 147
+#define CLKID_DPTX_AUD_DIV 148
+#define CLKID_DPTX_AUD 149
+#define CLKID_ISP_SEL 150
+#define CLKID_ISP_DIV 151
+#define CLKID_ISP 152
+#define CLKID_CVE_SEL 153
+#define CLKID_CVE_DIV 154
+#define CLKID_CVE 155
+#define CLKID_VGE_SEL 156
+#define CLKID_VGE_DIV 157
+#define CLKID_VGE 158
+#define CLKID_PP_SEL 159
+#define CLKID_PP_DIV 160
+#define CLKID_PP 161
+#define CLKID_GLB_SEL 162
+#define CLKID_GLB_DIV 163
+#define CLKID_GLB 164
+#define CLKID_USB_48M_DUALDIV_IN 165
+#define CLKID_USB_48M_DUALDIV_DIV 166
+#define CLKID_USB_48M_DUALDIV_SEL 167
+#define CLKID_USB_48M_DUALDIV 168
+#define CLKID_USB_48M 169
+#define CLKID_CAN0_PE_SEL 170
+#define CLKID_CAN0_PE_DIV 171
+#define CLKID_CAN0_PE 172
+#define CLKID_CAN1_PE_SEL 173
+#define CLKID_CAN1_PE_DIV 174
+#define CLKID_CAN1_PE 175
+#define CLKID_CAN0_FILTER_SEL 176
+#define CLKID_CAN0_FILTER_DIV 177
+#define CLKID_CAN0_FILTER 178
+#define CLKID_CAN1_FILTER_SEL 179
+#define CLKID_CAN1_FILTER_DIV 180
+#define CLKID_CAN1_FILTER 181
+#define CLKID_I3C_SEL 182
+#define CLKID_I3C_DIV 183
+#define CLKID_I3C 184
+#define CLKID_TS_DIV 185
+#define CLKID_TS 186
+#define CLKID_ETH_125M_DIV 187
+#define CLKID_ETH_125M 188
+#define CLKID_ETH_RMII_SEL 189
+#define CLKID_ETH_RMII_DIV 190
+#define CLKID_ETH_RMII 191
+#define CLKID_GEN_SEL 192
+#define CLKID_GEN_DIV 193
+#define CLKID_GEN 194
+#define CLKID_CLK24M_IN 195
+#define CLKID_CLK12_24M 196
+#define CLKID_MALI_0_SEL 197
+#define CLKID_MALI_0_DIV 198
+#define CLKID_MALI_0 199
+#define CLKID_MALI_1_SEL 200
+#define CLKID_MALI_1_DIV 201
+#define CLKID_MALI_1 202
+#define CLKID_MALI 203
+#define CLKID_MALI_STACK_0_SEL 204
+#define CLKID_MALI_STACK_0_DIV 205
+#define CLKID_MALI_STACK_0 206
+#define CLKID_MALI_STACK_1_SEL 207
+#define CLKID_MALI_STACK_1_DIV 208
+#define CLKID_MALI_STACK_1 209
+#define CLKID_MALI_STACK 210
+#define CLKID_DSPA_0_SEL 211
+#define CLKID_DSPA_0_DIV 212
+#define CLKID_DSPA_0 213
+#define CLKID_DSPA_1_SEL 214
+#define CLKID_DSPA_1_DIV 215
+#define CLKID_DSPA_1 216
+#define CLKID_DSPA 217
+#define CLKID_HEVCF_0_SEL 218
+#define CLKID_HEVCF_0_DIV 219
+#define CLKID_HEVCF_0 220
+#define CLKID_HEVCF_1_SEL 221
+#define CLKID_HEVCF_1_DIV 222
+#define CLKID_HEVCF_1 223
+#define CLKID_HEVCF 224
+#define CLKID_HCODEC_0_SEL 225
+#define CLKID_HCODEC_0_DIV 226
+#define CLKID_HCODEC_0 227
+#define CLKID_HCODEC_1_SEL 228
+#define CLKID_HCODEC_1_DIV 229
+#define CLKID_HCODEC_1 230
+#define CLKID_HCODEC 231
+#define CLKID_VPU_0_SEL 232
+#define CLKID_VPU_0_DIV 233
+#define CLKID_VPU_0 234
+#define CLKID_VPU_1_SEL 235
+#define CLKID_VPU_1_DIV 236
+#define CLKID_VPU_1 237
+#define CLKID_VPU 238
+#define CLKID_VAPB_0_SEL 239
+#define CLKID_VAPB_0_DIV 240
+#define CLKID_VAPB_0 241
+#define CLKID_VAPB_1_SEL 242
+#define CLKID_VAPB_1_DIV 243
+#define CLKID_VAPB_1 244
+#define CLKID_VAPB 245
+#define CLKID_GE2D 246
+#define CLKID_VPU_CLKB_TMP_SEL 247
+#define CLKID_VPU_CLKB_TMP_DIV 248
+#define CLKID_VPU_CLKB_TMP 249
+#define CLKID_VPU_CLKB_DIV 250
+#define CLKID_VPU_CLKB 251
+#define CLKID_HDMITX_SYS_SEL 252
+#define CLKID_HDMITX_SYS_DIV 253
+#define CLKID_HDMITX_SYS 254
+#define CLKID_HDMITX_PRIF_SEL 255
+#define CLKID_HDMITX_PRIF_DIV 256
+#define CLKID_HDMITX_PRIF 257
+#define CLKID_HDMITX_200M_SEL 258
+#define CLKID_HDMITX_200M_DIV 259
+#define CLKID_HDMITX_200M 260
+#define CLKID_HDMITX_AUD_SEL 261
+#define CLKID_HDMITX_AUD_DIV 262
+#define CLKID_HDMITX_AUD 263
+#define CLKID_HDMIRX_5M_SEL 264
+#define CLKID_HDMIRX_5M_DIV 265
+#define CLKID_HDMIRX_5M 266
+#define CLKID_HDMIRX_2M_SEL 267
+#define CLKID_HDMIRX_2M_DIV 268
+#define CLKID_HDMIRX_2M 269
+#define CLKID_HDMIRX_CFG_SEL 270
+#define CLKID_HDMIRX_CFG_DIV 271
+#define CLKID_HDMIRX_CFG 272
+#define CLKID_HDMIRX_HDCP2X_SEL 273
+#define CLKID_HDMIRX_HDCP2X_DIV 274
+#define CLKID_HDMIRX_HDCP2X 275
+#define CLKID_HDMIRX_ACR_REF_SEL 276
+#define CLKID_HDMIRX_ACR_REF_DIV 277
+#define CLKID_HDMIRX_ACR_REF 278
+#define CLKID_HDMIRX_METER_SEL 279
+#define CLKID_HDMIRX_METER_DIV 280
+#define CLKID_HDMIRX_METER 281
+#define CLKID_VID_LOCK_SEL 282
+#define CLKID_VID_LOCK_DIV 283
+#define CLKID_VID_LOCK 284
+#define CLKID_VDIN_MEAS_SEL 285
+#define CLKID_VDIN_MEAS_DIV 286
+#define CLKID_VDIN_MEAS 287
+#define CLKID_VID_PLL_DIV 288
+#define CLKID_VID_PLL_SEL 289
+#define CLKID_VID_PLL 290
+#define CLKID_VID_PLL_VCLK 291
+#define CLKID_VCLK0_SEL 292
+#define CLKID_VCLK0_IN 293
+#define CLKID_VCLK0_DIV 294
+#define CLKID_VCLK0 295
+#define CLKID_VCLK0_DIV1_EN 296
+#define CLKID_VCLK0_DIV2_EN 297
+#define CLKID_VCLK0_DIV2 298
+#define CLKID_VCLK0_DIV4_EN 299
+#define CLKID_VCLK0_DIV4 300
+#define CLKID_VCLK0_DIV6_EN 301
+#define CLKID_VCLK0_DIV6 302
+#define CLKID_VCLK0_DIV12_EN 303
+#define CLKID_VCLK0_DIV12 304
+#define CLKID_VCLK1_SEL 305
+#define CLKID_VCLK1_IN 306
+#define CLKID_VCLK1_DIV 307
+#define CLKID_VCLK1 308
+#define CLKID_VCLK1_DIV1_EN 309
+#define CLKID_VCLK1_DIV2_EN 310
+#define CLKID_VCLK1_DIV2 311
+#define CLKID_VCLK1_DIV4_EN 312
+#define CLKID_VCLK1_DIV4 313
+#define CLKID_VCLK1_DIV6_EN 314
+#define CLKID_VCLK1_DIV6 315
+#define CLKID_VCLK1_DIV12_EN 316
+#define CLKID_VCLK1_DIV12 317
+#define CLKID_VDAC_SEL 318
+#define CLKID_VDAC 319
+#define CLKID_ENCODER0_SEL 320
+#define CLKID_ENCODER0 321
+#define CLKID_ENCODER1_SEL 322
+#define CLKID_ENCODER1 323
+#define CLKID_HDMITX0_PIXEL_SEL 324
+#define CLKID_HDMITX0_PIXEL 325
+#define CLKID_HDMITX0_FE_SEL 326
+#define CLKID_HDMITX0_FE 327
+#define CLKID_HDMITX1_PIXEL_SEL 328
+#define CLKID_HDMITX1_PIXEL 329
+#define CLKID_HDMITX1_FE_SEL 330
+#define CLKID_HDMITX1_FE 331
+#define CLKID_CSI_PHY_SEL 332
+#define CLKID_CSI_PHY_DIV 333
+#define CLKID_CSI_PHY 334
+#define CLKID_DSI0_MEAS_SEL 335
+#define CLKID_DSI0_MEAS_DIV 336
+#define CLKID_DSI0_MEAS 337
+#define CLKID_DSI1_MEAS_SEL 338
+#define CLKID_DSI1_MEAS_DIV 339
+#define CLKID_DSI1_MEAS 340
+
+#endif /* __AMLOGIC_A9_PERIPHERALS_CLKC_H */
--
2.47.1
^ permalink raw reply related
* [PATCH v5 0/2] clk: amlogic: Add A9 peripherals clock controller
From: Jian Hu via B4 Relay @ 2026-06-30 2:36 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
This series adds Amlogic A9 peripherals clock support,
including dt-binding and peripherals clock driver.
Note that this driver depends on the A9 PLL driver, which is not yet
upstream. The Meson PLL framework is currently undergoing refactoring,
and the A9 PLL driver will be submitted as a follow-up series after
that work has been completed.
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
Changes in v5:
- Include <linux/module.h>.
- Add missing '0' suffixes to some clocks.
- Fix typo: "encorder1" -> "encoder1".
- Fix the parent clock for a9_hdmitx1_pixel.
- Link to v4: https://lore.kernel.org/r/20260618-a9_peripherals-v4-0-fe120de44e77@amlogic.com
Changes in v4:
- Expose channel 3 for gen_clk.
- Add missing '0' suffixes to somes.
- Use helper macro for vclk clocks definitions.
- Drop forward declaration.
- Drop CLK_HW_INIT* and revert to explicit clock declarations.
- Fix can clock channel number comment.
- Rename enc clocks to encoder0/encoder1.
- Link to v3: https://lore.kernel.org/r/20260610-a9_peripherals-v3-0-d07a78085f71@amlogic.com
Changes in v3:
- Add "depend on A9 pll" instructions in the cover-letter.
- Move COMPILE_TEST after 'depends on ARM64' reported by sashiko-bot.
- Fix usb_48m_pre_sel's parent reported by sashiko-bot.
- Fix gen_div width reported by sashiko-bot.
- Fix hdmitx1_pixel's parent reported by sashiko-bot.
- Link to v2: https://lore.kernel.org/r/20260603-a9_peripherals-v2-0-ee1b8c0a1e6c@amlogic.com
Changes in v2:
- Split the A9 clock driver and send the peripherals clock separately.
- Add COMPILE_TEST in Kconfig.
- Drop the 'optional'.
- Rename apb4 to soc.
- Sort the header file.
- Rename hifi to hifi0.
- Use CLK_HW_INIT_PARENTS_DATA to describe clk_init_data.
- Use CLK_HW_INIT_HW to describe clk_init_data.
- Use CLK_HW_INIT_PARENTS_HW to describe clk_init_data.
- Link to v1: https://lore.kernel.org/all/20260511-b4-a9_clk-v1-0-41cb4071b7c9@amlogic.com/
---
Jian Hu (2):
dt-bindings: clock: Add Amlogic A9 peripherals clock controller
clk: amlogic: Add A9 peripherals clock controller driver
.../clock/amlogic,a9-peripherals-clkc.yaml | 164 ++
drivers/clk/meson/Kconfig | 15 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a9-peripherals.c | 2095 ++++++++++++++++++++
.../clock/amlogic,a9-peripherals-clkc.h | 351 ++++
5 files changed, 2626 insertions(+)
---
base-commit: ca89c88bcf69daca829044c638a8163d5ce47af0
change-id: 20260603-a9_peripherals-4214e79705dc
Best regards,
--
Jian Hu <jian.hu@amlogic.com>
^ permalink raw reply
* [PATCH v3] Subject: [PATCH] net: gro: fix double aggregation of flush-marked skbs
From: Shiming Cheng @ 2026-06-30 2:35 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, horms, matthias.bgg,
angelogioacchino.delregno, willemb, daniel.zahka, alice, sd,
eilaimemedsnaimel, imv4bel, nbd, dsahern, netdev, linux-kernel,
linux-arm-kernel, linux-mediatek
Cc: stable, lena.wang, shiming.cheng
The new skb_gro_receive_list() function is missing a critical safety check
present in the legacy skb_gro_receive() path. Specifically, it does not
validate NAPI_GRO_CB(skb)->flush before allowing packet aggregation.
This allows already-GRO'd packets with existing frag_list to be
re-aggregated into a new GRO session, corrupting the frag_list chain
structure. When skb_segment() attempts to unpack these malformed packets,
it encounters invalid state and triggers a kernel panic.
Scenario (Tethering/Device forwarding):
1. Driver: Generated aggregated packet P1 via LRO with frag_list
2. Dev A: Receives aggregated fraglist packet and flush flag set
3. Dev A: Re-enters GRO, skb_gro_receive_list() is called
4. Missing flush check allows re-aggregation despite flush flag
5. Frag_list chain becomes corrupted (loops or dangling refs)
6. Dev B: TX path calls skb_segment(), crashes on corrupted frag_list
Root cause in skb_segment():
The check at line ~4891:
if (hsize <= 0 && i >= nfrags && skb_headlen(list_skb) &&
(skb_headlen(list_skb) == len || sg)) {
When frag_list is corrupted by double aggregation, when list_skb is
a NULL pointer from skb->next, skb_headlen(list_skb) dereference
NULL/corrupted pointers occurs.
Call Trace:
skb_headlen(NULL skb)
skb_segment
tcp_gso_segment
tcp4_gso_segment
inet_gso_segment
skb_mac_gso_segment
__skb_gso_segment
skb_gso_segment
validate_xmit_skb
validate_xmit_skb_list
sch_direct_xmit
qdisc_restart
__qdisc_run
qdisc_run
net_tx_action
Fix: Add NAPI_GRO_CB(skb)->flush validation to the early-return check in
skb_gro_receive_list(), matching the defensive programming pattern of
skb_gro_receive().
Fixes: 8928756d53d5 ("net: add fraglist GRO/GSO support")
Cc: stable@vger.kernel.org
Signed-off-by: Shiming Cheng <shiming.cheng@mediatek.com>
---
net/core/gro.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/core/gro.c b/net/core/gro.c
index 35f2f708f010..076247c1e662 100644
--- a/net/core/gro.c
+++ b/net/core/gro.c
@@ -229,7 +229,8 @@ int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb)
int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
{
- if (unlikely(p->len + skb->len >= 65536))
+ if (unlikely(p->len + skb->len >= 65536 ||
+ NAPI_GRO_CB(skb)->flush))
return -E2BIG;
if (!pskb_may_pull(skb, skb_gro_offset(skb))) {
--
2.45.2
^ permalink raw reply related
* [PATCH v5 2/2] arm64: dts: imx943-evk: Add Root Port node and according properties
From: hongxing.zhu @ 2026-06-30 2:30 UTC (permalink / raw)
To: sherry.sun, robh, krzk+dt, conor+dt, frank.li, s.hauer, festevam
Cc: kernel, devicetree, imx, linux-arm-kernel, linux-kernel,
Richard Zhu
In-Reply-To: <20260630023006.3247578-1-hongxing.zhu@oss.nxp.com>
From: Richard Zhu <hongxing.zhu@nxp.com>
Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.
Move the regulator to Root Port nodes as well, because that the PCI
pwrctrl framework had been integrated into pci-imx6 driver.
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Sherry Sun <sherry.sun@nxp.com>
---
arch/arm64/boot/dts/freescale/imx943-evk.dts | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx943-evk.dts b/arch/arm64/boot/dts/freescale/imx943-evk.dts
index 7cfd424689507..674410e541cba 100644
--- a/arch/arm64/boot/dts/freescale/imx943-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx943-evk.dts
@@ -1034,12 +1034,15 @@ &pcie0 {
<&pcie_ref_clk>;
clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux",
"ref", "extref";
- reset-gpio = <&pcal6416_i2c3_u46 3 GPIO_ACTIVE_LOW>;
- vpcie3v3aux-supply = <®_m2_wlan>;
supports-clkreq;
status = "okay";
};
+&pcie0_port0 {
+ reset-gpios = <&pcal6416_i2c3_u46 3 GPIO_ACTIVE_LOW>;
+ vpcie3v3aux-supply = <®_m2_wlan>;
+};
+
&pcie0_ep {
pinctrl-0 = <&pinctrl_pcie0>;
pinctrl-names = "default";
@@ -1058,12 +1061,15 @@ &pcie1 {
<&pcie_ref_clk>;
clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux",
"ref", "extref";
- reset-gpio = <&pcal6416_i2c3_u46 1 GPIO_ACTIVE_LOW>;
- vpcie3v3aux-supply = <®_slot_pwr>;
supports-clkreq;
status = "okay";
};
+&pcie1_port0 {
+ reset-gpios = <&pcal6416_i2c3_u46 1 GPIO_ACTIVE_LOW>;
+ vpcie3v3aux-supply = <®_slot_pwr>;
+};
+
&pcie1_ep {
pinctrl-0 = <&pinctrl_pcie1>;
pinctrl-names = "default";
--
2.34.1
^ permalink raw reply related
* [PATCH v5 1/2] arm64: dts: imx94: Add Root Port node
From: hongxing.zhu @ 2026-06-30 2:30 UTC (permalink / raw)
To: sherry.sun, robh, krzk+dt, conor+dt, frank.li, s.hauer, festevam
Cc: kernel, devicetree, imx, linux-arm-kernel, linux-kernel,
Richard Zhu
From: Richard Zhu <hongxing.zhu@nxp.com>
Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and pave the path to add the reset-gpios
and so on properties in Root Port later.
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Sherry Sun <sherry.sun@nxp.com>
---
arch/arm64/boot/dts/freescale/imx94.dtsi | 11 +++++++++++
arch/arm64/boot/dts/freescale/imx943.dtsi | 11 +++++++++++
2 files changed, 22 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx94.dtsi b/arch/arm64/boot/dts/freescale/imx94.dtsi
index 1f9035e6cf159..dfbb73603cb24 100644
--- a/arch/arm64/boot/dts/freescale/imx94.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx94.dtsi
@@ -1411,6 +1411,17 @@ pcie0: pcie@4c300000 {
power-domains = <&scmi_devpd IMX94_PD_HSIO_TOP>;
fsl,max-link-speed = <3>;
status = "disabled";
+
+ pcie0_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_ep: pcie-ep@4c300000 {
diff --git a/arch/arm64/boot/dts/freescale/imx943.dtsi b/arch/arm64/boot/dts/freescale/imx943.dtsi
index cf5b3dbb47ff7..01152fd0efa5e 100644
--- a/arch/arm64/boot/dts/freescale/imx943.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx943.dtsi
@@ -255,6 +255,17 @@ pcie1: pcie@4c380000 {
power-domains = <&scmi_devpd IMX94_PD_HSIO_TOP>;
fsl,max-link-speed = <3>;
status = "disabled";
+
+ pcie1_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_ep: pcie-ep@4c380000 {
--
2.34.1
^ permalink raw reply related
* Re: [PATCH 3/4] dt-bindings: ipmi: Add optional LPC properties to ASPEED BT devices
From: YC Hsieh @ 2026-06-30 2:24 UTC (permalink / raw)
To: Conor Dooley
Cc: Corey Minyard, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery,
openipmi-developer@lists.sourceforge.net,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-aspeed@lists.ozlabs.org
In-Reply-To: <20260629-bogus-vocation-db32e55a595f@spud>
Hi Conor,
Thanks for the review.
> Why can these two properties not just be an additional reg and
> interrupts entry?
The existing reg and interrupts properties describe BMC-side resources.
For this device, reg is the BMC-visible MMIO register range, and
interrupts is the interrupt from the BT controller to the BMC CPU. The
LPC IO address and SerIRQ described here are host-facing resources: the
LPC IO decode address is in the host LPC IO space, and the SerIRQ is
generated from the BMC toward the host.
There is no host interrupt controller represented in the BMC devicetree
to target with an interrupts entry, and adding another reg entry would
mix the BMC MMIO address space with the host LPC IO address space.
This follows the existing ASPEED KCS BMC bindings, which use
aspeed,lpc-io-reg and aspeed,lpc-interrupts for the same host-facing LPC
configuration.
Regards,
Yu-Che
************* Email Confidentiality Notice ********************
免責聲明:
本信件(或其附件)可能包含機密資訊,並受法律保護。如 台端非指定之收件者,請以電子郵件通知本電子郵件之發送者, 並請立即刪除本電子郵件及其附件和銷毀所有複印件。謝謝您的合作!
信驊科技以誠信正直原則永續經營企業,並已委由第三方公正單位勤業眾信及信驊科技獨立董事來管理匿名舉報系統,如各個利害關係人等有發現任何違法及違反公司從業道德、違反法令法規及專業準則、亦或霸凌及違反性別平等之情事,請直接透過以下可選擇匿名之舉報系統舉報,再次感謝您協助信驊持續邁向永續經營。信驊科技舉報網站連結:https://secure.conductwatch.com/aspeedtech/
DISCLAIMER:
This message (and any attachments) may contain legally privileged and/or other confidential information. If you have received it in error, please notify the sender by reply e-mail and immediately delete the e-mail and any attachments without copying or disclosing the contents. Thank you.
ASPEED Technology is committed to sustainable business practices based on integrity and honesty principles. In order to ensure that all information can be openly and transparently communicated, a third-party independent organization, Deloitte and ASPEED Technology's independent directors, have been entrusted to manage the anonymous reporting system. If any stakeholders discover any illegal activities, violations of the company's professional ethics, infringements of laws and regulations, or incidents of bullying and gender inequality, please directly report through the anonymous reporting system provided below. We thank you for your assistance in helping ASPEED Technology continue its journey towards sustainable operations: https://secure.conductwatch.com/aspeedtech/
^ permalink raw reply
* Re: [PATCH] kbuild: Use --force-group-allocation when linking modules
From: Nathan Chancellor @ 2026-06-30 1:54 UTC (permalink / raw)
To: Petr Pavlu
Cc: Nathan Chancellor, Nicolas Schier, Catalin Marinas, Will Deacon,
Peter Collingbourne, Sami Tolvanen, Daniel Gomez,
Luis Chamberlain, Aaron Tomlin, linux-kbuild, linux-arm-kernel,
linux-modules, linux-kernel
In-Reply-To: <20260612133139.1919042-1-petr.pavlu@suse.com>
On Fri, 12 Jun 2026 15:31:37 +0200, Petr Pavlu <petr.pavlu@suse.com> wrote:
> Specific code, such as outlined KASAN checks, may be placed in
> COMDAT-deduplicated sections. When linking modules as relocatable files,
> the linker by default preserves such groups, potentially leaving multiple
> copies in the resulting modules and unnecessary group metadata.
>
> Use --force-group-allocation to have the linker resolve the COMDAT groups
> and place their members as regular sections. The option is available from
> ld.bfd 2.29 and ld.lld 19.1.0.
>
> [...]
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
--
Cheers,
Nathan
^ permalink raw reply
* Re: [PATCH net v3] net: ti: icssg-prueth: fix XDP_TX from the AF_XDP zero-copy RX path
From: Jakub Kicinski @ 2026-06-30 1:12 UTC (permalink / raw)
To: David Carlier
Cc: danishanwar, rogerq, andrew+netdev, netdev, davem, edumazet,
pabeni, horms, m-malladi, hawk, john.fastabend, sdf, ast, daniel,
bpf, linux-arm-kernel, linux-kernel, stable
In-Reply-To: <20260625063121.24746-1-devnexen@gmail.com>
On Thu, 25 Jun 2026 07:31:21 +0100 David Carlier wrote:
> + PRUETH_SWDATA_XDPF_TX,
Sorry for the naming nit on v3 but XDPF_TX is ambiguous, I spent
a bunch of time digging thru the driver. It should really be called
XDPF_LOCAL or some such to indicate that the frame originates locally.
XDPF_TX is ambiguous.
--
pw-bot: cr
^ permalink raw reply
* [PATCH v5 1/3] dt-bindings: i2c: nuvoton,ma35d1-i2c: Add MA35D1 I2C controller
From: Zi-Yu Chen @ 2026-06-30 1:21 UTC (permalink / raw)
To: Andi Shyti
Cc: Jacky Huang, Shan-Chun Hung, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-i2c, devicetree,
linux-arm-kernel, linux-kernel, Zi-Yu Chen, Krzysztof Kozlowski
In-Reply-To: <20260630012106.3616821-1-zychennvt@gmail.com>
Add device tree binding documentation for the I2C controller
found in the Nuvoton MA35D1 SoC.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Zi-Yu Chen <zychennvt@gmail.com>
---
.../bindings/i2c/nuvoton,ma35d1-i2c.yaml | 63 +++++++++++++++++++
1 file changed, 63 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i2c/nuvoton,ma35d1-i2c.yaml
diff --git a/Documentation/devicetree/bindings/i2c/nuvoton,ma35d1-i2c.yaml b/Documentation/devicetree/bindings/i2c/nuvoton,ma35d1-i2c.yaml
new file mode 100644
index 000000000000..0713e1c1ecb8
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/nuvoton,ma35d1-i2c.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/nuvoton,ma35d1-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton MA35D1 I2C Controller
+
+maintainers:
+ - Zi-Yu Chen <zychennvt@gmail.com>
+
+description:
+ The Nuvoton MA35D1 I2C controller supports controller and optional target mode.
+
+allOf:
+ - $ref: /schemas/i2c/i2c-controller.yaml#
+
+properties:
+ compatible:
+ const: nuvoton,ma35d1-i2c
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-frequency:
+ description:
+ Desired I2C bus clock frequency in Hz. The absence of this property
+ indicates the default frequency 100 kHz.
+
+ resets:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - resets
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+ #include <dt-bindings/reset/nuvoton,ma35d1-reset.h>
+
+ i2c0: i2c@40800000 {
+ compatible = "nuvoton,ma35d1-i2c";
+ reg = <0x40800000 0x1000>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk I2C0_GATE>;
+ clock-frequency = <100000>;
+ resets = <&sys MA35D1_RESET_I2C0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
--
2.34.1
^ permalink raw reply related
* Re: [PATCHv2] firmware: ti_sci: simplify resource allocation
From: Rosen Penev @ 2026-06-30 1:42 UTC (permalink / raw)
To: Nishanth Menon
Cc: dmaengine, Peter Ujfalusi, Vignesh R, Vinod Koul, Frank Li,
Tero Kristo, Santosh Shilimkar, Kees Cook, Gustavo A. R. Silva,
linux-kernel, linux-arm-kernel, linux-hardening
In-Reply-To: <20260506110910.su2s6ncsi2xfdiwm@pureblood>
On Wed, May 6, 2026 at 4:09 AM Nishanth Menon <nm@ti.com> wrote:
>
> For some reason, replying drops the CC list. manually added them in.
Found the issue:
https://lore.kernel.org/lkml/20260630014129.1548147-1-rosenp@gmail.com/T/#u
>
> On 20:12-20260503, Rosen Penev wrote:
> > Use a flexible array member to combine allocations.
> >
> > Add __counted_by for extra runtime analysis.
> >
> > Fixup k3-udma as well since ti_sci_resource is used there as well and
> > needs fixing up to use kzalloc_flex.
> >
> > Signed-off-by: Rosen Penev <rosenp@gmail.com>
> > ---
> > v2: add k3-udma fixes.
> > drivers/dma/ti/k3-udma.c | 180 +++++++++++++------------
> > drivers/firmware/ti_sci.c | 7 +-
> > include/linux/soc/ti/ti_sci_protocol.h | 2 +-
> > 3 files changed, 98 insertions(+), 91 deletions(-)
>
> Since majority of the changes are via k3-udma.c, if this could go via
> dma tree, it would be nice. Else, please give an ack and I can carry on
> my tree.
>
> For the following:
> Reviewed-by: Nishanth Menon <nm@ti.com>
>
> > diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
> > index e027a2bd8f26..04d99c1fafa1 100644
> > --- a/drivers/firmware/ti_sci.c
> > +++ b/drivers/firmware/ti_sci.c
> > @@ -3574,16 +3574,11 @@ devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle,
> > bool valid_set = false;
> > int i, ret, res_count;
> >
> > - res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
> > + res = devm_kzalloc(dev, struct_size(res, desc, sets), GFP_KERNEL);
> > if (!res)
> > return ERR_PTR(-ENOMEM);
> >
> > res->sets = sets;
> > - res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
> > - GFP_KERNEL);
> > - if (!res->desc)
> > - return ERR_PTR(-ENOMEM);
> > -
> > for (i = 0; i < res->sets; i++) {
> > ret = handle->ops.rm_core_ops.get_range(handle, dev_id,
> > sub_types[i],
> > diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
> > index fd104b666836..7632bb11c862 100644
> > --- a/include/linux/soc/ti/ti_sci_protocol.h
> > +++ b/include/linux/soc/ti/ti_sci_protocol.h
> > @@ -599,7 +599,7 @@ struct ti_sci_handle {
> > struct ti_sci_resource {
> > u16 sets;
> > raw_spinlock_t lock;
> > - struct ti_sci_resource_desc *desc;
> > + struct ti_sci_resource_desc desc[] __counted_by(sets);
> > };
> >
> > #if IS_ENABLED(CONFIG_TI_SCI_PROTOCOL)
> > --
> > 2.54.0
> >
>
> --
> Regards,
> Nishanth Menon
> Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3 1A34 DDB5 849D 1736 249D
> https://ti.com/opensource
^ permalink raw reply
* [PATCH] ASoC: mediatek: mt2701: add COMPILE_TEST
From: Rosen Penev @ 2026-06-30 1:30 UTC (permalink / raw)
To: linux-sound
Cc: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
Matthias Brugger, AngeloGioacchino Del Regno, open list,
moderated list:ARM/Mediatek SoC support:Keyword:mediatek,
moderated list:ARM/Mediatek SoC support:Keyword:mediatek
Enable COMPILE_TEST for mt2701 to get extra build coverage as done with
other mediatek platforms.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
sound/soc/mediatek/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 4af7bbb58010..224746e7664f 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -7,7 +7,7 @@ config SND_SOC_MEDIATEK
config SND_SOC_MT2701
tristate "ASoC support for Mediatek MT2701 chip"
- depends on ARCH_MEDIATEK
+ depends on ARCH_MEDIATEK || COMPILE_TEST
select SND_SOC_MEDIATEK
help
This adds ASoC driver for Mediatek MT2701 boards
--
2.54.0
^ permalink raw reply related
* [PATCH] mtd: rawnand: atmel: use struct_size
From: Rosen Penev @ 2026-06-30 1:23 UTC (permalink / raw)
To: linux-mtd
Cc: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea,
moderated list:ARM/Microchip (AT91) SoC support, open list
The comment above makes it clear that this is a single element for
legacy handling. Clarify that with struct_size and avoid manual pointer
math.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/mtd/nand/raw/atmel/nand-controller.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index e7fdf532c5fe..8a19408abb63 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1799,8 +1799,7 @@ atmel_nand_controller_legacy_add_nands(struct atmel_nand_controller *nc)
* Legacy bindings only allow connecting a single NAND with a unique CS
* line to the controller.
*/
- nand = devm_kzalloc(nc->dev, sizeof(*nand) + sizeof(*nand->cs),
- GFP_KERNEL);
+ nand = devm_kzalloc(nc->dev, struct_size(nand, cs, 1), GFP_KERNEL);
if (!nand)
return -ENOMEM;
--
2.54.0
^ permalink raw reply related
* [PATCH v5 3/3] arm64: dts: nuvoton: Add I2C nodes for MA35D1 SoC
From: Zi-Yu Chen @ 2026-06-30 1:21 UTC (permalink / raw)
To: Andi Shyti
Cc: Jacky Huang, Shan-Chun Hung, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-i2c, devicetree,
linux-arm-kernel, linux-kernel, Zi-Yu Chen
In-Reply-To: <20260630012106.3616821-1-zychennvt@gmail.com>
Add I2C controller nodes to the MA35D1 SoC dtsi file.
Also, enable the I2C2 interface on the MA35D1 SOM board and
configure its pinctrl to allow communication with the onboard
NAU8822 audio codec
Signed-off-by: Zi-Yu Chen <zychennvt@gmail.com>
---
.../boot/dts/nuvoton/ma35d1-som-256m.dts | 20 ++++++
arch/arm64/boot/dts/nuvoton/ma35d1.dtsi | 72 +++++++++++++++++++
2 files changed, 92 insertions(+)
diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts b/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
index a029b660e8dc..1ffe41c03f3d 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
@@ -57,6 +57,18 @@ &clk {
"integer";
};
+&i2c2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+
+ nau8822: nau8822@1a {
+ compatible = "nuvoton,nau8822";
+ reg = <0x1a> ;
+ nuvoton,spk-btl;
+ };
+};
+
&pinctrl {
uart-grp {
pinctrl_uart0: uart0-pins {
@@ -100,6 +112,14 @@ pinctrl_uart16: uart16-pins {
power-source = <1>;
};
};
+
+ i2c-grp {
+ pinctrl_i2c2: i2c2-pins {
+ nuvoton,pins = <1 8 4>,
+ <1 9 4>;
+ bias-disable;
+ };
+ };
};
&uart0 {
diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi b/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
index 7228ad4735b5..28488889f564 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
@@ -372,6 +372,78 @@ uart15: serial@407f0000 {
status = "disabled";
};
+ i2c0: i2c@40800000 {
+ compatible = "nuvoton,ma35d1-i2c";
+ reg = <0x0 0x40800000 0x0 0x1000>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk I2C0_GATE>;
+ clock-frequency = <100000>;
+ resets = <&sys MA35D1_RESET_I2C0>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: i2c@40810000 {
+ compatible = "nuvoton,ma35d1-i2c";
+ reg = <0x0 0x40810000 0x0 0x1000>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk I2C1_GATE>;
+ clock-frequency = <100000>;
+ resets = <&sys MA35D1_RESET_I2C1>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c2: i2c@40820000 {
+ compatible = "nuvoton,ma35d1-i2c";
+ reg = <0x0 0x40820000 0x0 0x1000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk I2C2_GATE>;
+ clock-frequency = <100000>;
+ resets = <&sys MA35D1_RESET_I2C2>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c3: i2c@40830000 {
+ compatible = "nuvoton,ma35d1-i2c";
+ reg = <0x0 0x40830000 0x0 0x1000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk I2C3_GATE>;
+ clock-frequency = <100000>;
+ resets = <&sys MA35D1_RESET_I2C3>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c4: i2c@40840000 {
+ compatible = "nuvoton,ma35d1-i2c";
+ reg = <0x0 0x40840000 0x0 0x1000>;
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk I2C4_GATE>;
+ clock-frequency = <100000>;
+ resets = <&sys MA35D1_RESET_I2C4>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c5: i2c@40850000 {
+ compatible = "nuvoton,ma35d1-i2c";
+ reg = <0x0 0x40850000 0x0 0x1000>;
+ interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk I2C5_GATE>;
+ clock-frequency = <100000>;
+ resets = <&sys MA35D1_RESET_I2C5>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
uart16: serial@40880000 {
compatible = "nuvoton,ma35d1-uart";
reg = <0x0 0x40880000 0x0 0x100>;
--
2.34.1
^ permalink raw reply related
* [PATCH v5 2/3] i2c: ma35d1: Add Nuvoton MA35D1 I2C driver support
From: Zi-Yu Chen @ 2026-06-30 1:21 UTC (permalink / raw)
To: Andi Shyti
Cc: Jacky Huang, Shan-Chun Hung, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-i2c, devicetree,
linux-arm-kernel, linux-kernel, Zi-Yu Chen
In-Reply-To: <20260630012106.3616821-1-zychennvt@gmail.com>
Add I2C support for Nuvoton MA35D1 SoC.
The controller supports standard, fast and fast-plus modes,
and provides controller/target functionality.
Signed-off-by: Zi-Yu Chen <zychennvt@gmail.com>
---
drivers/i2c/busses/Kconfig | 13 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-ma35d1.c | 803 ++++++++++++++++++++++++++++++++
3 files changed, 817 insertions(+)
create mode 100644 drivers/i2c/busses/i2c-ma35d1.c
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index d7b89508311f..e69120d46977 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1602,4 +1602,17 @@ config I2C_VIRTIO
This driver can also be built as a module. If so, the module
will be called i2c-virtio.
+config I2C_MA35D1
+ tristate "Nuvoton MA35D1 I2C driver"
+ depends on ARCH_MA35 || COMPILE_TEST
+ select I2C_SLAVE
+ help
+ If you say yes to this option, support will be included for the
+ I2C controller in the Nuvoton MA35D1 SoC. This driver
+ supports the standard I2C bus protocols, including master and
+ slave modes.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-ma35d1.
+
endmenu
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 3755c54b3d82..ca75dae4955c 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -131,6 +131,7 @@ obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o
obj-$(CONFIG_I2C_XLP9XX) += i2c-xlp9xx.o
obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o
obj-$(CONFIG_I2C_GXP) += i2c-gxp.o
+obj-$(CONFIG_I2C_MA35D1) += i2c-ma35d1.o
# External I2C/SMBus adapter drivers
obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o
diff --git a/drivers/i2c/busses/i2c-ma35d1.c b/drivers/i2c/busses/i2c-ma35d1.c
new file mode 100644
index 000000000000..2044479b608e
--- /dev/null
+++ b/drivers/i2c/busses/i2c-ma35d1.c
@@ -0,0 +1,803 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 Nuvoton technology corporation.
+ *
+ * Author: Zi-Yu Chen <zychennvt@gmail.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/reset.h>
+
+/* MA35D1 I2C registers offset */
+#define MA35_CTL0 0x00
+#define MA35_ADDR0 0x04
+#define MA35_DAT 0x08
+#define MA35_STATUS0 0x0c
+#define MA35_CLKDIV 0x10
+#define MA35_TOCTL 0x14
+#define MA35_ADDR1 0x18
+#define MA35_ADDR2 0x1c
+#define MA35_ADDR3 0x20
+#define MA35_ADDRMSK0 0x24
+#define MA35_ADDRMSK1 0x28
+#define MA35_ADDRMSK2 0x2c
+#define MA35_ADDRMSK3 0x30
+#define MA35_WKCTL 0x3c
+#define MA35_WKSTS 0x40
+#define MA35_CTL1 0x44
+#define MA35_STATUS1 0x48
+#define MA35_TMCTL 0x4c
+#define MA35_BUSCTL 0x50
+#define MA35_BUSTCTL 0x54
+#define MA35_BUSSTS 0x58
+#define MA35_PKTSIZE 0x5c
+#define MA35_PKTCRC 0x60
+#define MA35_BUSTOUT 0x64
+#define MA35_CLKTOUT 0x68
+#define MA35_AUTOCNT 0x78
+
+/* MA35D1 I2C Status */
+/* Controller */
+#define MA35_M_START 0x08 /* Start */
+#define MA35_M_REPEAT_START 0x10 /* Controller Repeat Start */
+#define MA35_M_TRAN_ADDR_ACK 0x18 /* Controller Transmit Address ACK */
+#define MA35_M_TRAN_ADDR_NACK 0x20 /* Controller Transmit Address NACK */
+#define MA35_M_TRAN_DATA_ACK 0x28 /* Controller Transmit Data ACK */
+#define MA35_M_TRAN_DATA_NACK 0x30 /* Controller Transmit Data NACK */
+#define MA35_M_ARB_LOST 0x38 /* Controller Arbitration Lost */
+#define MA35_M_RECE_ADDR_ACK 0x40 /* Controller Receive Address ACK */
+#define MA35_M_RECE_ADDR_NACK 0x48 /* Controller Receive Address NACK */
+#define MA35_M_RECE_DATA_ACK 0x50 /* Controller Receive Data ACK */
+#define MA35_M_RECE_DATA_NACK 0x58 /* Controller Receive Data NACK */
+#define MA35_BUS_ERROR 0x00 /* Bus error */
+
+/* Target */
+#define MA35_S_REPEAT_START_STOP 0xa0 /* Target Transmit Repeat Start or Stop */
+#define MA35_S_TRAN_ADDR_ACK 0xa8 /* Target Transmit Address ACK */
+#define MA35_S_TRAN_DATA_ACK 0xb8 /* Target Transmit Data ACK */
+#define MA35_S_TRAN_DATA_NACK 0xc0 /* Target Transmit Data NACK */
+#define MA35_S_TRAN_LAST_DATA_ACK 0xc8 /* Target Transmit Last Data ACK */
+#define MA35_S_RECE_ADDR_ACK 0x60 /* Target Receive Address ACK */
+#define MA35_S_RECE_ARB_LOST 0x68 /* Target Receive Arbitration Lost */
+#define MA35_S_RECE_DATA_ACK 0x80 /* Target Receive Data ACK */
+#define MA35_S_RECE_DATA_NACK 0x88 /* Target Receive Data NACK */
+
+/* Other */
+#define MA35_ADDR_TRAN_ARB_LOST 0xb0 /* Address Transmit Arbitration Lost */
+#define MA35_BUS_RELEASED 0xf8 /* Bus Released */
+
+/* I2C_CTL constant definitions. */
+#define MA35_CTL_AA BIT(2)
+#define MA35_CTL_SI BIT(3)
+#define MA35_CTL_STO BIT(4)
+#define MA35_CTL_STA BIT(5)
+#define MA35_CTL_I2CEN BIT(6)
+#define MA35_CTL_INTEN BIT(7)
+#define MA35_CTL_SI_AA (MA35_CTL_SI | MA35_CTL_AA)
+#define MA35_CTL_STO_SI (MA35_CTL_STO | MA35_CTL_SI)
+#define MA35_CTL_STA_SI (MA35_CTL_STA | MA35_CTL_SI)
+#define MA35_CTL_STA_SI_AA (MA35_CTL_STA | MA35_CTL_SI | MA35_CTL_AA)
+#define MA35_CTL_STO_SI_AA (MA35_CTL_STO | MA35_CTL_SI | MA35_CTL_AA)
+
+/* Constants */
+#define MA35_CLKDIV_MSK GENMASK(15, 0)
+#define I2C_PM_TIMEOUT_MS 5000
+#define STOP_TIMEOUT_MS 50
+
+struct ma35d1_i2c {
+ spinlock_t lock;
+ wait_queue_head_t wait;
+ struct i2c_msg *msg;
+ unsigned int msg_num;
+ unsigned int msg_idx;
+ unsigned int msg_ptr;
+ int err;
+ int irq;
+ void __iomem *regs;
+ struct clk *clk;
+ struct device *dev;
+ struct i2c_adapter adap;
+ struct i2c_client *target;
+ struct reset_control *rst;
+};
+
+static inline bool ma35d1_is_controller_status(unsigned int status)
+{
+ return status >= MA35_M_START && status <= MA35_M_RECE_DATA_NACK;
+}
+
+/*
+ * ma35d1_i2c_write_ctl - Update the I2C control register
+ * @i2c: Pointer to the ma35d1 i2c instance
+ * @ctl: Control bits to set (e.g., MA35_CTL_STA, SI, AA)
+ *
+ * This helper reads CTL0, clears the sticky state-change bits (STA, STO, SI, AA),
+ * and then applies the new control bits provided by @ctl.
+ */
+static void ma35d1_i2c_write_ctl(struct ma35d1_i2c *i2c, unsigned int ctl)
+{
+ unsigned int val;
+
+ guard(spinlock_irqsave)(&i2c->lock);
+ val = readl(i2c->regs + MA35_CTL0);
+ val &= ~(MA35_CTL_STA_SI_AA | MA35_CTL_STO);
+ val |= ctl;
+ writel(val, i2c->regs + MA35_CTL0);
+}
+
+static void ma35d1_i2c_set_addr(struct ma35d1_i2c *i2c)
+{
+ unsigned int rw = i2c->msg->flags & I2C_M_RD;
+
+ writel(((i2c->msg->addr & 0x7f) << 1) | rw, i2c->regs + MA35_DAT);
+}
+
+static void ma35d1_i2c_controller_complete(struct ma35d1_i2c *i2c)
+{
+ i2c->msg_ptr = 0;
+ i2c->msg = NULL;
+ i2c->msg_idx++;
+ i2c->msg_num = 0;
+
+ wake_up(&i2c->wait);
+}
+
+static void ma35d1_i2c_disable_irq(struct ma35d1_i2c *i2c)
+{
+ u32 tmp;
+
+ guard(spinlock_irqsave)(&i2c->lock);
+ tmp = readl(i2c->regs + MA35_CTL0);
+ writel(tmp & ~MA35_CTL_INTEN, i2c->regs + MA35_CTL0);
+}
+
+static void ma35d1_i2c_enable_irq(struct ma35d1_i2c *i2c)
+{
+ u32 tmp;
+
+ guard(spinlock_irqsave)(&i2c->lock);
+ tmp = readl(i2c->regs + MA35_CTL0);
+ writel(tmp | MA35_CTL_INTEN, i2c->regs + MA35_CTL0);
+}
+
+static void ma35d1_i2c_reset(struct ma35d1_i2c *i2c)
+{
+ unsigned int clkdiv, slvaddr;
+
+ clkdiv = readl(i2c->regs + MA35_CLKDIV);
+ slvaddr = readl(i2c->regs + MA35_ADDR0);
+
+ reset_control_assert(i2c->rst);
+ usleep_range(10, 20);
+ reset_control_deassert(i2c->rst);
+
+ writel(clkdiv, (i2c->regs + MA35_CLKDIV));
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_I2CEN);
+
+ if (i2c->target)
+ writel(slvaddr, i2c->regs + MA35_ADDR0);
+}
+
+static void ma35d1_i2c_stop(struct ma35d1_i2c *i2c, int ret)
+{
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_STO_SI);
+
+ if (ret)
+ i2c->err = ret;
+
+ ma35d1_i2c_controller_complete(i2c);
+}
+
+/* Check if this is the last message in the set */
+static inline bool is_last_msg(struct ma35d1_i2c *i2c)
+{
+ return i2c->msg_idx >= (i2c->msg_num - 1);
+}
+
+/* Check if this is the last byte in the current message */
+static inline bool is_last_byte(struct ma35d1_i2c *i2c)
+{
+ return i2c->msg_ptr == i2c->msg->len - 1;
+}
+
+/* Check if reached the end of the current message */
+static inline bool is_msgend(struct ma35d1_i2c *i2c)
+{
+ return i2c->msg_ptr >= i2c->msg->len;
+}
+
+/*
+ * ma35d1_i2c_irq_target_trx - I2C Target state machine handler
+ * @i2c: ma35d1 i2c instance
+ * @i2c_status: hardware status code from MA35_STATUS0
+ */
+static void ma35d1_i2c_irq_target_trx(struct ma35d1_i2c *i2c,
+ unsigned long i2c_status)
+{
+ unsigned char byte;
+
+ switch (i2c_status) {
+ case MA35_S_RECE_ARB_LOST:
+ /*
+ * Arbitration lost during SLA+R/W (Address) phase.
+ * The hardware automatically switches to Target mode as our
+ * own slave address was detected.
+ */
+ i2c->err = -EAGAIN;
+ ma35d1_i2c_controller_complete(i2c);
+ i2c_slave_event(i2c->target, I2C_SLAVE_WRITE_REQUESTED, &byte);
+ break;
+
+ case MA35_S_RECE_ADDR_ACK:
+ /* Own SLA+W has been receive; ACK has been return */
+ i2c_slave_event(i2c->target, I2C_SLAVE_WRITE_REQUESTED, &byte);
+ break;
+
+ case MA35_S_TRAN_DATA_NACK:
+ case MA35_S_RECE_DATA_NACK:
+ /*
+ * Data byte or last data in I2CDAT has been transmitted and NACK received,
+ * or previously addressed with own SLA address and NACK returned.
+ */
+ break;
+
+ case MA35_S_RECE_DATA_ACK:
+ /* Previously address with own SLA address Data has been received;
+ * ACK has been returned
+ */
+ byte = readb(i2c->regs + MA35_DAT);
+ i2c_slave_event(i2c->target, I2C_SLAVE_WRITE_RECEIVED, &byte);
+ break;
+
+ case MA35_ADDR_TRAN_ARB_LOST:
+ /*
+ * Arbitration lost during Data byte transmission phase.
+ * The hardware automatically switches to Target mode as our
+ * own slave address was detected.
+ */
+ i2c->err = -EAGAIN;
+ ma35d1_i2c_controller_complete(i2c);
+ i2c_slave_event(i2c->target, I2C_SLAVE_WRITE_REQUESTED, &byte);
+ break;
+
+ case MA35_S_TRAN_ADDR_ACK:
+ /* Own SLA+R has been receive; ACK has been return */
+ i2c_slave_event(i2c->target, I2C_SLAVE_READ_REQUESTED, &byte);
+
+ writel(byte, i2c->regs + MA35_DAT);
+ break;
+
+ case MA35_S_TRAN_DATA_ACK:
+ i2c_slave_event(i2c->target, I2C_SLAVE_READ_PROCESSED, &byte);
+ writel(byte, i2c->regs + MA35_DAT);
+ break;
+
+ case MA35_S_REPEAT_START_STOP:
+ /* A STOP or repeated START has been received
+ * while still addressed as Target/Receiver
+ */
+ i2c_slave_event(i2c->target, I2C_SLAVE_STOP, &byte);
+ break;
+
+ default:
+ dev_err(i2c->dev, "Status 0x%02lx is NOT processed\n",
+ i2c_status);
+ break;
+ }
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_SI_AA);
+}
+
+/*
+ * ma35d1_i2c_irq_controller_trx - I2C Controller state machine handler
+ * @i2c: ma35d1 i2c instance
+ * @i2c_status: hardware status code from MA35_STATUS0
+ */
+static void ma35d1_i2c_irq_controller_trx(struct ma35d1_i2c *i2c,
+ unsigned long i2c_status)
+{
+ unsigned char byte;
+
+ /* Ensuring messages are absolutely valid in Controller mode. */
+ if (unlikely(!i2c->msg)) {
+ dev_err(i2c->dev, "Spurious controller interrupt (status: 0x%02lx)\n", i2c_status);
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_SI);
+ return;
+ }
+
+ switch (i2c_status) {
+ case MA35_M_START:
+ case MA35_M_REPEAT_START:
+ ma35d1_i2c_set_addr(i2c);
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_SI);
+ break;
+
+ case MA35_M_TRAN_ADDR_ACK:
+ case MA35_M_TRAN_DATA_ACK:
+ /* SLA+W has been transmitted and ACK has been received */
+ if (i2c_status == MA35_M_TRAN_ADDR_ACK) {
+ if (is_last_msg(i2c) && i2c->msg->len == 0) {
+ ma35d1_i2c_stop(i2c, 0);
+ return;
+ }
+ }
+
+ if (!is_msgend(i2c)) {
+ byte = i2c->msg->buf[i2c->msg_ptr++];
+ writel(byte, i2c->regs + MA35_DAT);
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_SI);
+ } else if (!is_last_msg(i2c)) {
+ dev_dbg(i2c->dev, "WRITE: Next Message\n");
+
+ i2c->msg_ptr = 0;
+ i2c->msg_idx++;
+ i2c->msg++;
+
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_STA | MA35_CTL_SI);
+ } else {
+ ma35d1_i2c_stop(i2c, 0);
+ }
+ break;
+
+ case MA35_M_TRAN_DATA_NACK:
+ ma35d1_i2c_stop(i2c, -EIO);
+ break;
+
+ case MA35_M_TRAN_ADDR_NACK:
+ case MA35_M_RECE_ADDR_NACK:
+ /* Controller Transmit Address NACK */
+ /* 0x20: SLA+W has been transmitted and NACK has been received */
+ /* 0x48: SLA+R has been transmitted and NACK has been received */
+ if (i2c->msg->flags & I2C_M_IGNORE_NAK) {
+ ma35d1_i2c_stop(i2c, 0);
+ } else {
+ dev_dbg(i2c->dev, "\n i2c: ack was not received\n");
+ ma35d1_i2c_stop(i2c, -ENXIO);
+ }
+ break;
+
+ case MA35_M_RECE_ADDR_ACK:
+ if (is_msgend(i2c)) {
+ if (is_last_msg(i2c)) {
+ ma35d1_i2c_stop(i2c, 0);
+ } else {
+ dev_dbg(i2c->dev, "READ: Next Transfer\n");
+
+ i2c->msg_ptr = 0;
+ i2c->msg_idx++;
+ i2c->msg++;
+
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_STA_SI);
+ }
+ } else if (i2c->msg->len == 1) {
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_SI);
+ } else {
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_SI_AA);
+ }
+ break;
+
+ case MA35_M_RECE_DATA_ACK:
+ case MA35_M_RECE_DATA_NACK:
+ /* DATA has been transmitted and ACK has been received */
+ byte = readb(i2c->regs + MA35_DAT);
+ i2c->msg->buf[i2c->msg_ptr++] = byte;
+
+ if (is_last_byte(i2c)) {
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_SI);
+ } else if (is_msgend(i2c)) {
+ if (is_last_msg(i2c)) {
+ dev_dbg(i2c->dev, "READ: Send Stop\n");
+
+ ma35d1_i2c_stop(i2c, 0);
+ } else {
+ dev_dbg(i2c->dev, "READ: Next Transfer\n");
+
+ i2c->msg_ptr = 0;
+ i2c->msg_idx++;
+ i2c->msg++;
+
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_STA_SI);
+ }
+ } else {
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_SI_AA);
+ }
+ break;
+
+ case MA35_M_ARB_LOST:
+ /* Arbitration Lost */
+ i2c->err = -EAGAIN;
+ ma35d1_i2c_controller_complete(i2c);
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_SI);
+ break;
+
+ default:
+ dev_err(i2c->dev, "Status 0x%02lx is NOT processed\n",
+ i2c_status);
+ ma35d1_i2c_stop(i2c, -EIO);
+ break;
+ }
+}
+
+static irqreturn_t ma35d1_i2c_irq(int irqno, void *dev_id)
+{
+ struct ma35d1_i2c *i2c = dev_id;
+ unsigned long status;
+
+ status = readl(i2c->regs + MA35_STATUS0);
+
+ if (status == MA35_BUS_ERROR) {
+ dev_err(i2c->dev, "Bus error during transfer\n");
+ ma35d1_i2c_stop(i2c, -EIO);
+ goto out;
+ }
+
+ if (ma35d1_is_controller_status(status))
+ ma35d1_i2c_irq_controller_trx(i2c, status);
+ else
+ ma35d1_i2c_irq_target_trx(i2c, status);
+
+out:
+ return IRQ_HANDLED;
+}
+
+static int ma35d1_i2c_doxfer(struct ma35d1_i2c *i2c, struct i2c_msg *msgs,
+ int num)
+{
+ unsigned long timeout;
+ unsigned int val;
+ int ret, err;
+
+ i2c->msg = msgs;
+ i2c->msg_num = num;
+ i2c->msg_ptr = 0;
+ i2c->msg_idx = 0;
+ i2c->err = 0;
+
+ ma35d1_i2c_enable_irq(i2c);
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_STA_SI);
+
+ timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+ ma35d1_i2c_disable_irq(i2c);
+ ret = i2c->msg_idx;
+
+ if (timeout == 0) {
+ dev_dbg(i2c->dev, "xfer timeout\n");
+ ret = -ETIMEDOUT;
+ goto reset;
+ }
+
+ err = readl_poll_timeout(i2c->regs + MA35_CTL0, val,
+ !(val & MA35_CTL_STO), 100,
+ STOP_TIMEOUT_MS * 1000);
+ if (err) {
+ dev_err(i2c->dev, "bus idle timeout\n");
+ ret = -EBUSY;
+ goto reset;
+ } else if (i2c->err) {
+ dev_dbg(i2c->dev, "xfer error %d\n", i2c->err);
+ ret = i2c->err;
+ }
+ return ret;
+
+reset:
+ ma35d1_i2c_reset(i2c);
+ return ret;
+}
+
+static int ma35d1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
+{
+ struct ma35d1_i2c *i2c = i2c_get_adapdata(adap);
+ int ret;
+
+ ret = pm_runtime_resume_and_get(i2c->dev);
+ if (ret)
+ return ret;
+
+ ret = ma35d1_i2c_doxfer(i2c, msgs, num);
+
+ if (i2c->target) {
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_SI_AA);
+ ma35d1_i2c_enable_irq(i2c);
+ }
+ pm_runtime_put_autosuspend(i2c->dev);
+
+ return ret;
+}
+
+static int ma35d1_reg_target(struct i2c_client *target)
+{
+ struct ma35d1_i2c *i2c = i2c_get_adapdata(target->adapter);
+ unsigned int slvaddr;
+ int ret;
+
+ if (i2c->target)
+ return -EBUSY;
+
+ if (target->flags & I2C_CLIENT_TEN)
+ return -EAFNOSUPPORT;
+
+ /* Keep device active for target mode listening. */
+ ret = pm_runtime_resume_and_get(i2c->dev);
+ if (ret) {
+ dev_err(i2c->dev, "failed to resume i2c controller\n");
+ return ret;
+ }
+
+ i2c->target = target;
+
+ slvaddr = target->addr << 1;
+ writel(slvaddr, i2c->regs + MA35_ADDR0);
+
+ /* I2C enter SLV mode */
+ ma35d1_i2c_write_ctl(i2c, MA35_CTL_SI_AA);
+
+ ma35d1_i2c_enable_irq(i2c);
+
+ return 0;
+}
+
+static int ma35d1_unreg_target(struct i2c_client *target)
+{
+ struct ma35d1_i2c *i2c = i2c_get_adapdata(target->adapter);
+ int ret;
+
+ if (!i2c->target)
+ return -EINVAL;
+
+ /* Disable I2C interrupt */
+ ma35d1_i2c_disable_irq(i2c);
+
+ i2c->target = NULL;
+
+ ret = pm_runtime_put_sync(i2c->dev);
+ if (ret < 0)
+ dev_err(i2c->dev, "failed to suspend i2c controller");
+
+ return 0;
+}
+
+/* Declare Our I2C Functionality */
+static u32 ma35d1_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+/* I2C Bus Registration Info */
+static const struct i2c_algorithm ma35d1_i2c_algorithm = {
+ .xfer = ma35d1_i2c_xfer,
+ .functionality = ma35d1_i2c_func,
+ .reg_target = ma35d1_reg_target,
+ .unreg_target = ma35d1_unreg_target,
+};
+
+static int ma35d1_i2c_suspend(struct device *dev)
+{
+ struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
+ unsigned int val;
+
+ /* Prepare for wake-up from I2C events if target mode is active */
+ if (i2c->target) {
+ val = readl(i2c->regs + MA35_CTL0);
+ val |= (MA35_CTL_SI | MA35_CTL_AA);
+ writel(val, i2c->regs + MA35_CTL0);
+
+ /* Setup wake-up control */
+ writel(0x1, i2c->regs + MA35_WKCTL);
+
+ /* Clear pending wake-up flags */
+ val = readl(i2c->regs + MA35_WKSTS);
+ writel(val, i2c->regs + MA35_WKSTS);
+
+ enable_irq_wake(i2c->irq);
+
+ ma35d1_i2c_enable_irq(i2c);
+ return 0;
+ }
+ return pm_runtime_force_suspend(dev);
+}
+
+static int ma35d1_i2c_resume(struct device *dev)
+{
+ struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
+ unsigned int val;
+
+ if (i2c->target) {
+ /* Disable wake-up */
+ writel(0x0, i2c->regs + MA35_WKCTL);
+
+ /* Clear pending wake-up flags */
+ val = readl(i2c->regs + MA35_WKSTS);
+ writel(val, i2c->regs + MA35_WKSTS);
+
+ disable_irq_wake(i2c->irq);
+ return 0;
+ }
+ return pm_runtime_force_resume(dev);
+}
+
+static int ma35d1_i2c_runtime_suspend(struct device *dev)
+{
+ struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
+ unsigned int val;
+
+ /* Disable I2C controller */
+ val = readl(i2c->regs + MA35_CTL0);
+ val &= ~MA35_CTL_I2CEN;
+ writel(val, i2c->regs + MA35_CTL0);
+
+ clk_disable(i2c->clk);
+
+ return 0;
+}
+
+static int ma35d1_i2c_runtime_resume(struct device *dev)
+{
+ struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
+ unsigned int val;
+ int ret;
+
+ ret = clk_enable(i2c->clk);
+ if (ret) {
+ dev_err(dev, "failed to enable clock in resume\n");
+ return ret;
+ }
+
+ /* Enable I2C controller */
+ val = readl(i2c->regs + MA35_CTL0);
+ val |= MA35_CTL_I2CEN;
+ writel(val, i2c->regs + MA35_CTL0);
+
+ return 0;
+}
+
+static void ma35d1_i2c_pm_cleanup(void *data)
+{
+ struct device *dev = data;
+
+ pm_runtime_dont_use_autosuspend(dev);
+
+ pm_runtime_disable(dev);
+
+ /*
+ * prevents usage count inconsistencies if the user
+ * has manually forced the device active via sysfs.
+ */
+ if (!pm_runtime_status_suspended(dev))
+ ma35d1_i2c_runtime_suspend(dev);
+}
+
+
+static int ma35d1_i2c_probe(struct platform_device *pdev)
+{
+ struct ma35d1_i2c *i2c;
+ struct resource *res;
+ int ret, clkdiv;
+ unsigned int busfreq;
+ struct device *dev = &pdev->dev;
+
+ i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
+ if (!i2c)
+ return -ENOMEM;
+
+ init_waitqueue_head(&i2c->wait);
+ spin_lock_init(&i2c->lock);
+
+ i2c->dev = dev;
+
+ i2c->clk = devm_clk_get_prepared(dev, NULL);
+ if (IS_ERR(i2c->clk))
+ return dev_err_probe(dev, PTR_ERR(i2c->clk),
+ "failed to get core clk\n");
+
+ i2c->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(i2c->regs))
+ return PTR_ERR(i2c->regs);
+
+ i2c->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+ if (IS_ERR(i2c->rst))
+ return dev_err_probe(dev, PTR_ERR(i2c->rst),
+ "failed to get reset control\n");
+
+ /* Setup info block for the I2C core */
+ strscpy(i2c->adap.name, "ma35d1-i2c", sizeof(i2c->adap.name));
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.algo = &ma35d1_i2c_algorithm;
+ i2c->adap.retries = 2;
+ i2c->adap.algo_data = i2c;
+ i2c->adap.dev.parent = &pdev->dev;
+ i2c->adap.dev.of_node = pdev->dev.of_node;
+ i2c_set_adapdata(&i2c->adap, i2c);
+
+ /* Default to 100kHz if not specified in DT */
+ busfreq = 100000;
+ device_property_read_u32(dev, "clock-frequency", &busfreq);
+
+ /* Calculate divider based on the current peripheral clock rate */
+ clkdiv = DIV_ROUND_CLOSEST(clk_get_rate(i2c->clk), busfreq * 4) - 1;
+ if (clkdiv < 0 || clkdiv > 0xffff)
+ return dev_err_probe(dev, -EINVAL, "invalid clkdiv value: %d\n",
+ clkdiv);
+
+ i2c->irq = platform_get_irq(pdev, 0);
+ if (i2c->irq < 0)
+ return dev_err_probe(dev, i2c->irq, "failed to get irq\n");
+
+ platform_set_drvdata(pdev, i2c);
+
+ pm_runtime_set_autosuspend_delay(dev, I2C_PM_TIMEOUT_MS);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_enable(dev);
+
+ ret = devm_add_action_or_reset(dev, ma35d1_i2c_pm_cleanup, dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register PM cleanup\n");
+
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to resume device\n");
+
+ writel(FIELD_PREP(MA35_CLKDIV_MSK, clkdiv), i2c->regs + MA35_CLKDIV);
+
+ ret = devm_request_irq(dev, i2c->irq, ma35d1_i2c_irq, 0, dev_name(dev),
+ i2c);
+ if (ret) {
+ dev_err_probe(dev, ret, "cannot claim IRQ %d\n", i2c->irq);
+ goto rpm_put;
+ }
+
+ ret = devm_i2c_add_adapter(dev, &i2c->adap);
+ if (ret) {
+ dev_err_probe(dev, ret, "failed to add bus to i2c core\n");
+ goto rpm_put;
+ }
+
+ pm_runtime_put_autosuspend(dev);
+
+ dev_info(&i2c->adap.dev, "%pa MA35D1 I2C adapter registered\n",
+ &res->start);
+ return 0;
+
+rpm_put:
+ pm_runtime_put_sync(dev);
+ return ret;
+}
+
+static const struct dev_pm_ops ma35d1_i2c_pmops = {
+ SYSTEM_SLEEP_PM_OPS(ma35d1_i2c_suspend, ma35d1_i2c_resume)
+ RUNTIME_PM_OPS(ma35d1_i2c_runtime_suspend,
+ ma35d1_i2c_runtime_resume, NULL)
+};
+
+static const struct of_device_id ma35d1_i2c_of_match[] = {
+ { .compatible = "nuvoton,ma35d1-i2c" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ma35d1_i2c_of_match);
+
+static struct platform_driver ma35d1_i2c_driver = {
+ .probe = ma35d1_i2c_probe,
+ .driver = {
+ .name = "ma35d1-i2c",
+ .of_match_table = ma35d1_i2c_of_match,
+ .pm = pm_ptr(&ma35d1_i2c_pmops),
+ },
+};
+module_platform_driver(ma35d1_i2c_driver);
+
+MODULE_AUTHOR("Zi-Yu Chen <zychennvt@gmail.com>");
+MODULE_DESCRIPTION("MA35D1 I2C Bus Driver");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related
* [PATCH v5 0/3] i2c: ma35d1: Add support for MA35D1 I2C controller
From: Zi-Yu Chen @ 2026-06-30 1:21 UTC (permalink / raw)
To: Andi Shyti
Cc: Jacky Huang, Shan-Chun Hung, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-i2c, devicetree,
linux-arm-kernel, linux-kernel, Zi-Yu Chen
This series adds support for the I2C controller found in the Nuvoton
MA35D1 SoC. The driver supports controller and optional target mode
and runtime power management.
The implementation has been tested on the Nuvoton MA35D1 SOM board.
Changes in v5:
- Patch 2 (driver):
- Add spinlock protection for MA35_CTL0 register access.
- Add NULL pointer check for i2c->msg in the ISR.
- Use devres-managed cleanup (devm_add_action_or_reset) for runtime PM.
- Use pm_runtime_force_suspend/resume() for Controller mode
system sleep.
- Control I2CEN bit enabling/disabling via runtime PM.
- Refactor arbitration lost handling in state machines.
- Remove unsupported I2C_FUNC_PROTOCOL_MANGLING flag.
- Clean up readl_poll_timeout() parameters, retry loop, and
unused macros.
v4: https://lore.kernel.org/r/20260610030208.2020275-1-zychennvt@gmail.com/
Changes in v4:
- Patch 1 (dt-bindings):
- Update example interrupt number.
- Patch 2 (driver):
- Remove redundant spinlocks and fix 'irq' type to signed.
- Fix target address recovery in ma35d1_i2c_reset().
- Refactor IRQ handler for multi-msg reads and NACK/IGNORE_NAK.
- Fix timeout UAF via explicit IRQ disabling during recovery.
- Drop IRQF_SHARED and fix PM paths in probe/unregistration.
- Limit suspend/resume wakeup logic to target mode only.
- Patch 3 (dts):
- Add missing i2c0 node to dtsi.
- Switch SoM configuration from i2c1 to i2c2 with updated pinctrl.
- Add nau8822 audio codec node under i2c2 on the SoM board.
- Drop redundant i2c0 alias and clean up dtsi property ordering.
v3: https://lore.kernel.org/r/20260512073953.564323-1-zychennvt@gmail.com/
Changes in v3:
- Fix minor DTS formatting issues (whitespace, missing newline)
v2: https://lore.kernel.org/r/20260316063726.41048-1-zychennvt@gmail.com
Changes in v2:
- Overall:
- Rebase on linux-i2c/i2c-next
- Switched terminology from "master/slave" to "controller/target".
- Patch 1 (dt-bindings):
- Simplified description and fixed 'reg' size in example.
- Patch 2 (driver):
- Modernized using devm_*, generic device properties, and FIELD_PREP/GENMASK.
- Optimized power management by moving clock control to runtime PM.
- Simplified code by removing redundant .remove(), .owner, and inlines.
- Added dev_err_probe() and default bus frequency handling.
- Patch 3 (dts):
- Moved i2c aliases to board dts and reordered nodes alphabetically.
v1: https://lore.kernel.org/r/20260302020822.13936-1-zychennvt@gmail.com
Zi-Yu Chen (3):
dt-bindings: i2c: nuvoton,ma35d1-i2c: Add MA35D1 I2C controller
i2c: ma35d1: Add Nuvoton MA35D1 I2C driver support
arm64: dts: nuvoton: Add I2C nodes for MA35D1 SoC
.../bindings/i2c/nuvoton,ma35d1-i2c.yaml | 63 ++
.../boot/dts/nuvoton/ma35d1-som-256m.dts | 20 +
arch/arm64/boot/dts/nuvoton/ma35d1.dtsi | 72 ++
drivers/i2c/busses/Kconfig | 13 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-ma35d1.c | 803 ++++++++++++++++++
6 files changed, 972 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i2c/nuvoton,ma35d1-i2c.yaml
create mode 100644 drivers/i2c/busses/i2c-ma35d1.c
--
2.34.1
^ permalink raw reply
* Re: [PATCH v2 2/2] arm64: dts: qcom: kaanapali: fix traceNoC probe issue
From: Jie Gan @ 2026-06-30 1:03 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark
Cc: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Tingwei Zhang, Jingyi Wang,
Abel Vesa, Yuanfang Zhang, linux-arm-msm, devicetree,
linux-kernel, coresight, linux-arm-kernel
In-Reply-To: <20260629142848.GB1812158@e132581.arm.com>
On 6/29/2026 10:28 PM, Leo Yan wrote:
> On Mon, Jun 29, 2026 at 10:08:17AM +0800, Jie Gan wrote:
>
> [...]
>
>> Can I fix the issue by adding "arm,primecell-periphid" property. That's
>> would be the best temp solution as it avoids breaking the original design of
>> both the TraceNoC AMBA driver and interconnect TraceNoC platform driver.
>
> Before proceeding with the "arm,primecell-periphid" property, could you
> clarify a bit:
>
> - For an interconnect TraceNoC, what would be the consequence of
> enabling ATID? Would it simply be a no-op, or are there any side
> effects? Or is the concern that the trace IDs could be exhausted?
>
TPDM0(or ATB source) -> interconnect TraceNoC0 -> Aggregator TraceNoc ->
sink
TPDM1(or ATB source) -> interconnect TraceNoC1 -> Aggregator TraceNoc ->
sink
We only have one Aggregator TraceNoC and many interconnect TraceNoC
devices for one platform. All interconnect TraceNoC devices are
connected to Aggregator TraceNoC devices in the topology, so the itnoc
doesnt need an ATID.
That's the design purpose from hardware perspective.
> - How can you guarantee that a interconnect TraceNoC will never
> require ATID in the future?
>
The interconnect TraceNoC is primarily introduced to reduce routing
complexity in the hardware design. It is typically deployed as an
intermediate TraceNoC that connects to an Aggregator TraceNoC (AG TraceNoC).
For example, a modem subsystem may contain many TPDM devices. Directly
connecting every TPDM to the AG TraceNoC would result in significant
wiring complexity. Instead, an itnoc is placed within the modem
subsystem to locally aggregate the TPDM connections. All TPDMs first
connect to the itnoc, and the itnoc then connects to the system-level AG
TraceNoC.
From a hardware perspective, there is no fundamental difference between
an itnoc and an AG TraceNoC. They use the same TraceNoC hardware
implementation and share the same AMBA bus type. The distinction is
purely functional: an itnoc is used for local trace aggregation within a
subsystem, whereas an AG TraceNoC serves as the top-level aggregation
point for the SoC.
Thanks,
Jie
>> The TraceNoC device here must be treated as an AMBA device and I am
>> continuing to investigate the issue with our hardware team.
>
>> We aim to fix it from hardware perspetive for existing platforms if possible
>> and ensure it is fixed in future platforms.
>
> I'm concerned that all of use end up repeatedly fixing similar issues
> whenever hardware configurations change or modules are reused in
> different topologies.
>
> For example, if future platforms may require ATID support for an
> interconnect TraceNoC, then the issue will pop up again.
>
> Thanks,
> Leo
^ permalink raw reply
* Re: [PATCH v2] usb: dwc3: imx8mp: make dwc3_imx_glue_ops static and rename to imx8mp
From: Thinh Nguyen @ 2026-06-30 0:38 UTC (permalink / raw)
To: Ben Dooks
Cc: Thinh Nguyen, Greg Kroah-Hartman, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-usb@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1c0f84bf-267c-4dc2-a756-1997cf3871d2@codethink.co.uk>
On Mon, Jun 29, 2026, Ben Dooks wrote:
> On 26/06/2026 23:32, Thinh Nguyen wrote:
> > On Tue, Jun 23, 2026, Ben Dooks wrote:
> > > The dwc3_imx_glue_ops is not used outside this file, and technically this
> > > is the dwc3-imx8mp driver so whilst making this static to avoid the
> > > following warning, rename it dwc3_imx8mp_glue_ops to distinguish it from
> > > the other driver which also has dwc3_imx_glue_ops.
> > >
> > > Fixes:
> > > drivers/usb/dwc3/dwc3-imx8mp.c:176:22: warning: symbol 'dwc3_imx_glue_ops' was not declared. Should it be static?
> > >
> > > Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> > > ---
> > > drivers/usb/dwc3/dwc3-imx8mp.c | 8 ++++----
> > > 1 file changed, 4 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c
> > > index 1cf96540b66e..de8c17bc940d 100644
> > > --- a/drivers/usb/dwc3/dwc3-imx8mp.c
> > > +++ b/drivers/usb/dwc3/dwc3-imx8mp.c
> > > @@ -158,7 +158,7 @@ static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx)
> > > return IRQ_HANDLED;
> > > }
> > > -static void dwc3_imx_pre_set_role(struct dwc3 *dwc, enum usb_role role)
> > > +static void dwc3_imx8mp_pre_set_role(struct dwc3 *dwc, enum usb_role role)
> > > {
> > > if (role == USB_ROLE_HOST)
> > > /*
> > > @@ -173,8 +173,8 @@ static void dwc3_imx_pre_set_role(struct dwc3 *dwc, enum usb_role role)
> > > pm_runtime_use_autosuspend(dwc->dev);
> > > }
> > > -struct dwc3_glue_ops dwc3_imx_glue_ops = {
> > > - .pre_set_role = dwc3_imx_pre_set_role,
> > > +static struct dwc3_glue_ops dwc3_imx8mp_glue_ops = {
> > > + .pre_set_role = dwc3_imx8mp_pre_set_role,
> > > };
> > > static int dwc3_imx8mp_probe(struct platform_device *pdev)
> > > @@ -266,7 +266,7 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
> > > goto put_dwc3;
> > > }
> > > - dwc3->glue_ops = &dwc3_imx_glue_ops;
> > > + dwc3->glue_ops = &dwc3_imx8mp_glue_ops;
> > > if (dwc3->dr_mode == USB_DR_MODE_HOST)
> > > pm_runtime_dont_use_autosuspend(dwc3->dev);
> > > --
> > > 2.37.2.352.g3c44437643
> > >
> >
> > Please add Fixes and Cc stable tags and backport this change also.
>
> Hi, I thought fixes was only for bugs not warnings and stable is
> only for serious bugs?
>
>
Does it trigger -Werror build failure? If so, it should go in stable.
Thanks,
Thinh
^ permalink raw reply
* Re: [PATCH v10 0/9] perf cs-etm: Support thread stack and callchain
From: Namhyung Kim @ 2026-06-30 0:36 UTC (permalink / raw)
To: Leo Yan
Cc: Arnaldo Carvalho de Melo, John Garry, Will Deacon, James Clark,
Mike Leach, Suzuki K Poulose, Mark Rutland, Alexander Shishkin,
Jiri Olsa, Ian Rogers, Adrian Hunter, Al Grant, Paschalis Mpeis,
Amir Ayupov, linux-arm-kernel, coresight, linux-perf-users,
Leo Yan
In-Reply-To: <20260617-b4-arm_cs_callchain_support_v1-v10-0-e8b6e5d63db5@arm.com>
Hi Leo,
On Wed, Jun 17, 2026 at 04:08:51PM +0100, Leo Yan wrote:
> This series adds thread-stack and synthesized callchain support for Arm
> CoreSight, which comes from older series [1] but heavily rewritten.
>
> CS ETM previously kept last-branch state in a per-trace-queue buffer.
> That effectively makes the state per CPU, while the call/return history
> belongs to a thread. This series moves branch tracking to the common
> thread-stack code.
>
> The series records CoreSight branches with thread_stack__event(), uses
> thread_stack__br_sample() for last branch entries, flushes thread stacks
> after decoder resets.
>
> A decoder reset between AUX trace buffers is treated as a global trace
> discontinuity, so all thread stacks are flushed, so avoids carrying
> stale call/return history across a trace discontinuity.
>
> One limitation remains for instructions emulated by the kernel. In that
> case the exception return address may not match the return address
> stored in the thread stack, because after exception return can be one
> instruction ahead. The stack can still recover when a later return
> matches an upper caller. Given emulated instructions are not the common
> target for performance callchain analysis. Supporting this would require
> extending the common thread-stack path to accept both the real target
> address and an adjusted address for stack matching, so this series
> leaves that extra complexity out.
>
> The series has been tested on Orion6 board:
>
> perf test 136 -vvv
> 136: CoreSight synthesized callchain:
> --- start ---
> test child forked, pid 3539
> ---- end(0) ----
> 136: CoreSight synthesized callchain : Ok
>
> perf script --itrace=g16i10il64
>
> callchain_test 17468 [005] 1031003.229943: 10 instructions:
> aaaac32507c4 main+0x8 (/home/kernel/leoy/test_cs_callchain/callchain_test)
> ffff90bd225c __libc_start_call_main+0x7c (/usr/lib/aarch64-linux-gnu/libc.so.6)
> ffff90bd233c call_init+0x9c (inlined)
> ffff90bd233c __libc_start_main_impl+0x9c (inlined)
> aaaac3250670 _start+0x30 (/home/kernel/leoy/test_cs_callchain/callchain_test)
>
> callchain_test 17468 [005] 1031003.229943: 10 instructions:
> aaaac3250774 do_svc+0xc (/home/kernel/leoy/test_cs_callchain/callchain_test)
> aaaac3250798 print+0xc (/home/kernel/leoy/test_cs_callchain/callchain_test)
> aaaac32507b0 foo+0xc (/home/kernel/leoy/test_cs_callchain/callchain_test)
> aaaac32507c8 main+0xc (/home/kernel/leoy/test_cs_callchain/callchain_test)
> ffff90bd225c __libc_start_call_main+0x7c (/usr/lib/aarch64-linux-gnu/libc.so.6)
> ffff90bd233c call_init+0x9c (inlined)
> ffff90bd233c __libc_start_main_impl+0x9c (inlined)
> aaaac3250670 _start+0x30 (/home/kernel/leoy/test_cs_callchain/callchain_test)
>
> callchain_test 17468 [005] 1031003.229944: 10 instructions:
> ffff800080010c20 vectors+0x420 ([kernel.kallsyms])
> aaaac3250784 do_svc+0x1c (/home/kernel/leoy/test_cs_callchain/callchain_test)
> aaaac3250798 print+0xc (/home/kernel/leoy/test_cs_callchain/callchain_test)
> aaaac32507b0 foo+0xc (/home/kernel/leoy/test_cs_callchain/callchain_test)
> aaaac32507c8 main+0xc (/home/kernel/leoy/test_cs_callchain/callchain_test)
> ffff90bd225c __libc_start_call_main+0x7c (/usr/lib/aarch64-linux-gnu/libc.so.6)
> ffff90bd233c call_init+0x9c (inlined)
> ffff90bd233c __libc_start_main_impl+0x9c (inlined)
> aaaac3250670 _start+0x30 (/home/kernel/leoy/test_cs_callchain/callchain_test)
>
> Note, the test fails on Juno board which is caused by many discontinuity
> packets (mainly caused by NO_SYNC elem). This is likely caused by the
> FIFO overflow on the path.
>
> [1] https://lore.kernel.org/linux-arm-kernel/20200220052701.7754-1-leo.yan@linaro.org/
>
> Signed-off-by: Leo Yan <leo.yan@arm.com>
Will you send a new version or want to merge this? It seems there are
some remaining comments from Sashiko.
Thanks,
Namhyung
> ---
> Changes in v10:
> - Change to syscall(SYS_gettid) for build failure on x86 (James).
> - Extracted sample thread stack into cs_etm__sample_branch_stack().
> - Link to v9: https://lore.kernel.org/r/20260616-b4-arm_cs_callchain_support_v1-v9-0-f8fad931c413@arm.com
>
> Changes in v9:
> - Added patch 01 to fixed thread leak during trace queue init (sashiko).
> - Added check in instruction and branch samples in
> cs_etm__add_stack_event() (sashiko).
> - Released frontend_thread properly in cs_etm__context() (sashiko).
> - Refined cs_etm__flush_all_stack() to use switch (sashiko).
> - Gathered James' review tags.
> - Rebased on the latest perf-tools-next.
> - Link to v8: https://lore.kernel.org/r/20260611-b4-arm_cs_callchain_support_v1-v8-0-737948584fea@arm.com
>
> Changes in v8:
> - Updated test_arm_coresight_disasm.sh to pass "--itrace=b" and updated
> examples in arm-cs-trace-disasm.py (James).
> - Removed static annotation in callchain workload and renamed functions
> with prefix "callchain_" to reduce naming conflict (James).
> - For callchain test pre-condition check, removed the aarch64 check and
> added the root permission check (James).
> - Resolved the shellcheck errors (James).
> - Link to v7: https://lore.kernel.org/r/20260611-b4-arm_cs_callchain_support_v1-v7-0-1ba770c862ae@arm.com
>
> Changes in v7:
> - Rebased on the latest perf-tools-next.
> - Used struct_size() for allocation callchain struct (James).
> - Added a helper cs_etm__packet_has_taken_branch() (James).
> - Minor improvements for the callchain test (used record-ctl FIFO and
> reworked the validation callstack push / pop).
> - Link to v6: https://lore.kernel.org/r/20260526-b4-arm_cs_callchain_support_v1-v6-0-f9f49f53c9dd@arm.com
>
> Changes in v6:
> - Heavily rewrote the patches since restarted the work after 6 years.
> - Changed to use the common thread-stack for branch stack and callchain
> management.
> - Added a callchain test.
> - Link to v5: https://lore.kernel.org/linux-arm-kernel/20200220052701.7754-1-leo.yan@linaro.org/
>
> Changes in v5:
> - Addressed Mike's suggestion for performance improvement for function
> cs_etm__instr_addr() for quick calculation for non T32;
> - Removed the patch 'perf cs-etm: Synchronize instruction sample with
> the thread stack' (Mike);
> - Fixed the issue for exception is taken for branch target address
> accessing, for the branch sample and stack thread handling, the
> related patches are 01, 02, 07;
> - Fixed the stack thread handling for instruction emulation and single
> step with patches 08, 09.
> - Link to v4: https://lore.kernel.org/linux-arm-kernel/20200203020716.31832-1-leo.yan@linaro.org/
>
> ---
> Leo Yan (9):
> perf cs-etm: Fix thread leaks on trace queue init failure
> perf cs-etm: Filter synthesized branch samples
> perf cs-etm: Decode ETE exception packets
> perf cs-etm: Refactor instruction size handling
> perf cs-etm: Use thread-stack for last branch entries
> perf cs-etm: Flush thread stacks after decoder reset
> perf cs-etm: Support call indentation
> perf cs-etm: Synthesize callchains for instruction samples
> perf test: Add Arm CoreSight callchain test
>
> tools/perf/Documentation/perf-test.txt | 6 +-
> tools/perf/scripts/python/arm-cs-trace-disasm.py | 9 +-
> tools/perf/tests/builtin-test.c | 1 +
> tools/perf/tests/shell/coresight/callchain.sh | 172 ++++++++++
> .../shell/coresight/test_arm_coresight_disasm.sh | 4 +-
> tools/perf/tests/tests.h | 1 +
> tools/perf/tests/workloads/Build | 2 +
> tools/perf/tests/workloads/callchain.c | 33 ++
> tools/perf/util/cs-etm.c | 377 +++++++++++++--------
> 9 files changed, 454 insertions(+), 151 deletions(-)
> ---
> base-commit: 8c214ad8cb8d692c82c6466b8e88973dbfa8e064
> change-id: 20260521-b4-arm_cs_callchain_support_v1-2c2a70719bcc
>
> Best regards,
> --
> Leo Yan <leo.yan@arm.com>
>
^ permalink raw reply
* Re: [PATCH v4 2/2] arm64: io: apply the device store-release workaround once per block write
From: Shanker Donthineni @ 2026-06-29 23:09 UTC (permalink / raw)
To: Vladimir Murzin, Catalin Marinas, Will Deacon
Cc: Jason Gunthorpe, linux-arm-kernel, Mark Rutland, linux-kernel,
linux-doc, Vikram Sethi, Jason Sequeira
In-Reply-To: <97b62a6f-a514-46bb-9ee8-81f563220f6a@arm.com>
Hi Vladimir,
On 6/29/2026 5:48 AM, Vladimir Murzin wrote:
> External email: Use caution opening links or attachments
>
>
> Hi,
>
> On 6/25/26 19:24, Shanker Donthineni wrote:
>> The generic memset_io()/memcpy_toio() are built on __raw_write*(), so on
>> parts with the NVIDIA Olympus device store/load ordering erratum the
>> ARM64_WORKAROUND_DEVICE_STORE_RELEASE workaround promotes every store in
>> the block to a store-release. Each stlr* carries a barrier cost, so block
>> MMIO becomes O(n) store-releases, making a block copy many times slower
>> than a single ordered burst and growing with the transfer size.
>>
>> Provide arm64 memset_io()/memcpy_toio() that emit plain str* in the loop
>> and order the whole block against subsequent loads with a single
>> trailing dmb osh on affected CPUs (a no-op elsewhere, preserving the
>> relaxed contract of these helpers). This keeps block MMIO writes at
>> one-barrier cost rather than scaling with the transfer size.
>>
>> Performance (NVIDIA Olympus, write-combining MMIO to a device BAR, single
>> PE pinned; per-call cost in ns; consecutive writes ping-pong between two
>> buffers so repeated stores are not coalesced; iowrite64/iowrite32 =
>> __iowrite{64,32}_copy()):
>>
>> Table 1 - arm64 memset_io/memcpy_toio (this patch)
>> +-------+-----------+-----------+-----------+-------------+
>> | size | iowrite64 | iowrite32 | memset_io | memcpy_toio |
>> +-------+-----------+-----------+-----------+-------------+
>> | 8B | 231.6 ns | 231.6 ns | 232.4 ns | 232.4 ns |
>> | 16B | 231.7 ns | 231.9 ns | 232.7 ns | 232.6 ns |
>> | 32B | 231.9 ns | 232.7 ns | 232.9 ns | 232.9 ns |
>> | 64B | 232.7 ns | 235.0 ns | 233.7 ns | 233.6 ns |
>> | 128B | 233.6 ns | 235.8 ns | 234.4 ns | 234.3 ns |
>> | 256B | 237.7 ns | 276.8 ns | 264.0 ns | 276.7 ns |
>> | 512B | 237.7 ns | 277.1 ns | 238.1 ns | 277.6 ns |
>> | 1KB | 253.7 ns | 279.3 ns | 276.1 ns | 294.1 ns |
>> | 2KB | 295.0 ns | 318.7 ns | 288.5 ns | 308.3 ns |
>> | 4KB | 365.9 ns | 381.4 ns | 365.7 ns | 381.3 ns |
>> +-------+-----------+-----------+-----------+-------------+
>> all four helpers end with a single trailing barrier (dmb osh).
>>
>> Table 2 - generic per-store memset_io/memcpy_toio
>> +-------+-----------+-----------+-------------+--------------+
>> | size | iowrite64 | iowrite32 | memset_io | memcpy_toio |
>> +-------+-----------+-----------+-------------+--------------+
>> | 8B | 231.6 ns | 231.6 ns | 229.0 ns | 229.0 ns |
>> | 16B | 231.7 ns | 231.9 ns | 458.4 ns | 458.5 ns |
>> | 32B | 231.9 ns | 232.7 ns | 917.4 ns | 917.5 ns |
>> | 64B | 232.7 ns | 234.8 ns | 1835.4 ns | 1835.5 ns |
>> | 128B | 233.6 ns | 235.8 ns | 3670.9 ns | 3670.8 ns |
>> | 256B | 237.7 ns | 276.7 ns | 7341.6 ns | 7341.6 ns |
>> | 512B | 237.7 ns | 279.4 ns | 14001.4 ns | 14001.3 ns |
>> | 1KB | 253.7 ns | 279.1 ns | 28631.5 ns | 28631.8 ns |
>> | 2KB | 279.4 ns | 317.9 ns | 57276.3 ns | 57275.2 ns |
>> | 4KB | 365.7 ns | 381.5 ns | 114564.4 ns | 114563.6 ns |
>> +-------+-----------+-----------+-------------+--------------+
>> the generic memset_io()/memcpy_toio() build on __raw_write*(), which the
>> workaround promotes to store-release, so every store is individually
>> ordered - hence O(n) in the store count.
>>
>> The arm64 versions stay flat at one-barrier cost while the generic
>> per-store writers collapse to O(n): at 4KB ~314x slower (~115 us vs
>> ~366 ns).
>>
>> Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com>
>> ---
>> arch/arm64/include/asm/io.h | 5 +++
>> arch/arm64/kernel/io.c | 82 +++++++++++++++++++++++++++++++++++++
>> 2 files changed, 87 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
>> index 69e0fa004d31..649503f347bc 100644
>> --- a/arch/arm64/include/asm/io.h
>> +++ b/arch/arm64/include/asm/io.h
>> @@ -266,6 +266,11 @@ __iowrite64_copy(void __iomem *to, const void *from, size_t count)
>> }
>> #define __iowrite64_copy __iowrite64_copy
>>
>> +void memset_io(volatile void __iomem *dst, int c, size_t count);
>> +#define memset_io memset_io
>> +void memcpy_toio(volatile void __iomem *dst, const void *src, size_t count);
>> +#define memcpy_toio memcpy_toio
>> +
>> /*
>> * I/O memory mapping functions.
>> */
>> diff --git a/arch/arm64/kernel/io.c b/arch/arm64/kernel/io.c
>> index fe86ada23c7d..b5fd9ee6d9eb 100644
>> --- a/arch/arm64/kernel/io.c
>> +++ b/arch/arm64/kernel/io.c
>> @@ -5,9 +5,91 @@
>> * Copyright (C) 2012 ARM Ltd.
>> */
>>
>> +#include <linux/align.h>
>> #include <linux/export.h>
>> #include <linux/types.h>
>> #include <linux/io.h>
>> +#include <linux/unaligned.h>
>> +
>> +#include <asm/alternative.h>
>> +
>> +/*
>> + * ARM64_WORKAROUND_DEVICE_STORE_RELEASE promotes every raw MMIO store
>> + * (__raw_write*()) to a store-release on affected CPUs. The generic
>> + * memset_io()/memcpy_toio() are built on those helpers, so the workaround would
>> + * emit one store-release per element and turn a block write into O(n) ordered
>> + * stores - far more costly than the single barrier a block actually needs.
>> + *
>> + * Provide arm64 versions that emit plain STR in the loop and order the whole
>> + * block against subsequent loads with one trailing DMB OSH, patched in only on
>> + * affected CPUs (a no-op elsewhere, so the relaxed contract of these helpers is
>> + * preserved).
>> + *
>> + * This capability is currently enabled only for the NVIDIA Olympus device
>> + * store/load ordering erratum, where a Device-nGnR* load may be observed before
>> + * an older, non-overlapping Device-nGnR* store to the same peripheral.
>> + */
>> +static __always_inline void iomem_block_store_barrier(void)
>> +{
>> + asm volatile(ALTERNATIVE("nop", "dmb osh",
>> + ARM64_WORKAROUND_DEVICE_STORE_RELEASE)
>> + : : : "memory");
>> +}
>> +
>> +void memset_io(volatile void __iomem *dst, int c, size_t count)
>> +{
>> + u64 qc = (u8)c;
>> +
>> + qc *= ~0ULL / 0xff;
>> +
>> + while (count && !IS_ALIGNED((__force unsigned long)dst, sizeof(u64))) {
>> + asm volatile("strb %w0, [%1]" : : "rZ"((u8)c), "r"(dst) : "memory");
>> + dst++;
>> + count--;
>> + }
>> + while (count >= sizeof(u64)) {
>> + asm volatile("str %x0, [%1]" : : "rZ"(qc), "r"(dst) : "memory");
>> + dst += sizeof(u64);
>> + count -= sizeof(u64);
>> + }
>> + while (count) {
>> + asm volatile("strb %w0, [%1]" : : "rZ"((u8)c), "r"(dst) : "memory");
>> + dst++;
>> + count--;
>> + }
>> +
>> + iomem_block_store_barrier();
>> +}
>> +EXPORT_SYMBOL(memset_io);
>> +
>> +void memcpy_toio(volatile void __iomem *dst, const void *src, size_t count)
>> +{
>> + while (count && !IS_ALIGNED((__force unsigned long)dst, sizeof(u64))) {
>> + asm volatile("strb %w0, [%1]"
>> + : : "rZ"(*(const u8 *)src), "r"(dst) : "memory");
>> + src++;
>> + dst++;
>> + count--;
>> + }
>> + while (count >= sizeof(u64)) {
>> + asm volatile("str %x0, [%1]"
>> + : : "rZ"(get_unaligned((const u64 *)src)), "r"(dst)
> Why do we need get_unaligned() here? I understand this came from
> the generic implementation, where it needs to handle architectures
> that do not support unaligned accesses. But IIUC this is not an
> issue for arm64, and there was no special handling in memcpy_toio()
> before 0110feaaf6d0 ("arm64: Use new fallback IO memcpy/memset").
> Am I missing something?
Thanks for the review.
I used get_unaligned() because I was trying to keep the arm64 implementation
as close as possible to the generic memcpy_toio() implementation in
lib/iomem_copy.c. However, you are right that before commit 0110feaaf6d0
(“arm64: Use new fallback IO memcpy/memset”), the arm64 implementation
used a direct u64 load and did not explicitly handle source alignment. I
can restore the previous arm64 form in v5 if that is preferred.
>> + : "memory");
>> + src += sizeof(u64);
>> + dst += sizeof(u64);
>> + count -= sizeof(u64);
>> + }
>> + while (count) {
>> + asm volatile("strb %w0, [%1]"
>> + : : "rZ"(*(const u8 *)src), "r"(dst) : "memory");
>> + src++;
>> + dst++;
>> + count--;
>> + }
>> +
>> + iomem_block_store_barrier();
> It is perhaps a matter of taste, but having the inline assembly
> here (and in memset_io()) might make the code clearer. To a
> casual reader, it would be obvious that the barrier is not
> guaranteed and is only applicable to ARM64_WORKAROUND_DEVICE_STORE_RELEASE,
> without having to jump back and forth through the code.
>
> Obliviously maintainers might have different preference ;)
Regarding the barrier, iomem_block_store_barrier() is declared
static __always_inline, so it does not add a function call. The nop/dmb
osh alternative is emitted directly in each caller. I used the helper to
avoid duplicating the alternative sequence.
I understand that placing the assembly directly in both functions could
make its conditional nature more obvious. I do not have a strong preference
and am happy to follow Will’s and Catalin’s preference here.
-Shanker
^ permalink raw reply
* Re: [PATCH v4 0/2] arm64: errata: NVIDIA Olympus device store/load ordering
From: Shanker Donthineni @ 2026-06-29 23:08 UTC (permalink / raw)
To: Vladimir Murzin, Catalin Marinas, Will Deacon
Cc: Jason Gunthorpe, linux-arm-kernel, Mark Rutland, linux-kernel,
linux-doc, Vikram Sethi, Jason Sequeira
In-Reply-To: <381fb71c-0a2c-4dec-98a3-56ad88e190c6@arm.com>
Hi Vladimir,
On 6/29/2026 5:45 AM, Vladimir Murzin wrote:
> External email: Use caution opening links or attachments
>
>
> Hi,
>
> On 6/25/26 19:24, Shanker Donthineni wrote:
>> This series works around the NVIDIA Olympus device store/load ordering
>> erratum (T410-OLY-1027): a Device-nGnR* load can be observed by a
>> peripheral before an older, non-overlapping Device-nGnR* store to the
>> same peripheral, breaking the program order that drivers rely on for
>> MMIO and potentially leaving a device in an incorrect state.
>>
>> Patch 1 adds the workaround. It promotes the raw MMIO store helpers
>> (__raw_writeb/w/l/q, and therefore writel()/writel_relaxed()) to
>> store-release on affected CPUs, and promotes the trailing DGH of the
>> write-combining __iowrite{32,64}_copy() helpers to dmb osh. Everything is
>> gated on a new ARM64_WORKAROUND_DEVICE_STORE_RELEASE cpucap and patched
>> in only on affected parts, so it is a no-op elsewhere.
>>
>> Patch 2 provides arm64 memset_io()/memcpy_toio(). The generic versions
>> are built on __raw_write*(), so patch 1 would promote every store in a
>> block to a store-release; as each STLR drains the write-combining buffer,
>> block MMIO becomes O(n) store-releases. The arm64 versions emit plain
>> STR in the loop and order the whole block with a single trailing dmb osh,
>> keeping block MMIO at one-barrier cost.
>>
>> Performance: NVIDIA Olympus, write-combining MMIO to a device BAR, single
>> PE pinned; per-call cost in ns. Consecutive writes ping-pong between two
>> buffers so repeated stores are not coalesced. iowrite64/iowrite32 =
>> __iowrite{64,32}_copy().
>>
>> Table 1 - workaround off (CONFIG_NVIDIA_OLYMPUS_1027_ERRATUM=n)
>> +-------+-----------+-----------+-----------+-------------+
>> | size | iowrite64 | iowrite32 | memset_io | memcpy_toio |
>> +-------+-----------+-----------+-----------+-------------+
>> | 8B | 67.9 ns | 67.8 ns | 3.6 ns | 3.6 ns |
>> | 16B | 67.9 ns | 67.8 ns | 4.0 ns | 4.0 ns |
>> | 32B | 67.9 ns | 67.9 ns | 4.6 ns | 4.6 ns |
>> | 64B | 69.1 ns | 69.1 ns | 69.1 ns | 69.0 ns |
>> | 128B | 138.3 ns | 138.3 ns | 138.4 ns | 138.3 ns |
>> | 256B | 276.6 ns | 276.6 ns | 276.6 ns | 276.7 ns |
>> | 512B | 276.6 ns | 276.5 ns | 276.6 ns | 276.6 ns |
>> | 1KB | 276.6 ns | 278.4 ns | 276.6 ns | 276.6 ns |
>> | 2KB | 278.4 ns | 278.4 ns | 275.9 ns | 276.6 ns |
>> | 4KB | 365.7 ns | 365.7 ns | 365.7 ns | 365.7 ns |
>> +-------+-----------+-----------+-----------+-------------+
>> relaxed/no-flush: memset_io()/memcpy_toio() issue plain stores with no
>> trailing dgh() or barrier, unlike __iowrite*_copy() which ends with dgh().
>>
>> Table 2 - workaround on, arm64 memset_io/memcpy_toio (this series)
>> +-------+-----------+-----------+-----------+-------------+
>> | size | iowrite64 | iowrite32 | memset_io | memcpy_toio |
>> +-------+-----------+-----------+-----------+-------------+
>> | 8B | 231.6 ns | 231.6 ns | 232.4 ns | 232.4 ns |
>> | 16B | 231.7 ns | 231.9 ns | 232.7 ns | 232.6 ns |
>> | 32B | 231.9 ns | 232.7 ns | 232.9 ns | 232.9 ns |
>> | 64B | 232.7 ns | 235.0 ns | 233.7 ns | 233.6 ns |
>> | 128B | 233.6 ns | 235.8 ns | 234.4 ns | 234.3 ns |
>> | 256B | 237.7 ns | 276.8 ns | 264.0 ns | 276.7 ns |
>> | 512B | 237.7 ns | 277.1 ns | 238.1 ns | 277.6 ns |
>> | 1KB | 253.7 ns | 279.3 ns | 276.1 ns | 294.1 ns |
>> | 2KB | 295.0 ns | 318.7 ns | 288.5 ns | 308.3 ns |
>> | 4KB | 365.9 ns | 381.4 ns | 365.7 ns | 381.3 ns |
>> +-------+-----------+-----------+-----------+-------------+
>> all four helpers end with a single trailing barrier (dmb osh).
>>
>> Table 3 - workaround on, generic per-store memset_io/memcpy_toio
>> +-------+-----------+-----------+-------------+--------------+
>> | size | iowrite64 | iowrite32 | memset_io | memcpy_toio |
>> +-------+-----------+-----------+-------------+--------------+
>> | 8B | 231.6 ns | 231.6 ns | 229.0 ns | 229.0 ns |
>> | 16B | 231.7 ns | 231.9 ns | 458.4 ns | 458.5 ns |
>> | 32B | 231.9 ns | 232.7 ns | 917.4 ns | 917.5 ns |
>> | 64B | 232.7 ns | 234.8 ns | 1835.4 ns | 1835.5 ns |
>> | 128B | 233.6 ns | 235.8 ns | 3670.9 ns | 3670.8 ns |
>> | 256B | 237.7 ns | 276.7 ns | 7341.6 ns | 7341.6 ns |
>> | 512B | 237.7 ns | 279.4 ns | 14001.4 ns | 14001.3 ns |
>> | 1KB | 253.7 ns | 279.1 ns | 28631.5 ns | 28631.8 ns |
>> | 2KB | 279.4 ns | 317.9 ns | 57276.3 ns | 57275.2 ns |
>> | 4KB | 365.7 ns | 381.5 ns | 114564.4 ns | 114563.6 ns |
>> +-------+-----------+-----------+-------------+--------------+
>> the generic memset_io()/memcpy_toio() build on __raw_write*(), which the
>> workaround promotes to store-release, so every store is individually
>> ordered - hence O(n) in the store count.
>>
>> Tables 2 and 3 show why patch 2 is needed: the generic per-store block
>> writers collapse to O(n) under the workaround (4KB ~314x slower, ~115 us
>> vs ~366 ns), while the arm64 versions stay flat at one-barrier cost.
> That's interesting. With the way the patch set is structured, it
> now looks like:
>
> 1. Fix the erratum, but cause a performance regression.
> 2. Restore the performance regression and (re)apply the erratum
> workaround.
>
> Would it make sense to avoid introducing the performance
> regression in the first place by structuring the patch set
> slightly differently?
>
> 1. (Re)introduce arm64 memset_io()/memcpy_toio().
> 2. Fix the erratum once for all
>
> What do you reckon?
Yes, that ordering makes sense.
I can restructure v5 so that patch 1 introduces the arm64 memset_{to}io()
implementations while preserving the existing behavior. Patch 2 will
then add the complete erratum workaround, including the conditional
trailing DMB for those block-write helpers. This avoids introducing
the intermediate performance regression and keeps each commit
independently usable.
Will and Catalin, could you please share your thoughts on this approach?
-Shanker
^ permalink raw reply
* Re: [PATCH] net: stmmac: fix missed le32_to_cpu()
From: Jakub Kicinski @ 2026-06-29 22:44 UTC (permalink / raw)
To: Ben Dooks
Cc: Maxime Chevallier, Andrew Lunn, David S. Miller, Eric Dumazet,
Paolo Abeni, Maxime Coquelin, Alexandre Torgue,
Russell King (Oracle), netdev, linux-stm32, linux-arm-kernel,
linux-kernel
In-Reply-To: <74e05f3d-39a6-4a4c-8bc3-d4f23a54ef69@codethink.co.uk>
On Mon, 29 Jun 2026 12:11:08 +0100 Ben Dooks wrote:
> On 25/06/2026 08:07, Maxime Chevallier wrote:
> > Ben, what's this "prototype" sparse ? a custom tool of yours that
> > you used to find that ?
>
> I have an RFC to add variadic and thus also printf/scanf formatting
> to sparse. This is waiting on review after the original got re-worked
> to add scanf and a few other bug-fixed and shuffles.
>
> Ref: https://marc.info/?l=linux-sparse&m=178185274600679&w=2
Ah, makes sense. This most definitely need to be part of the commit
message.
^ permalink raw reply
* [PATCH v2 1/1] dt-bindings: mfd: st,stmpe: fix typo st,stmpe601 (should be st,stmpe610)
From: Frank.Li @ 2026-06-29 22:37 UTC (permalink / raw)
To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Maxime Coquelin, Alexandre Torgue, Linus Walleij,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM/STM32 ARCHITECTURE,
moderated list:ARM/STM32 ARCHITECTURE, open list
Cc: imx, Frank Li
From: Frank Li <Frank.Li@nxp.com>
The compatible string "st,stmpe601" is a typo and does not correspond to
any existing STMPE device in either the driver or DTS files. The correct
compatible string is "st,stmpe610".
Fix the typo to ensure proper schema matching and eliminate the
following CHECK_DTBS warning:
imx53-m53evk.dtb: /soc/bus@60000000/i2c@63fc4000/touchscreen@41: failed to match any schema with compatible: ['st,stmpe610']
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
Documentation/devicetree/bindings/mfd/st,stmpe.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/mfd/st,stmpe.yaml b/Documentation/devicetree/bindings/mfd/st,stmpe.yaml
index 4bb05d544901c..ddb27ae64ba37 100644
--- a/Documentation/devicetree/bindings/mfd/st,stmpe.yaml
+++ b/Documentation/devicetree/bindings/mfd/st,stmpe.yaml
@@ -20,7 +20,7 @@ allOf:
properties:
compatible:
enum:
- - st,stmpe601
+ - st,stmpe610
- st,stmpe801
- st,stmpe811
- st,stmpe1600
--
2.43.0
^ permalink raw reply related
* [PATCH v3 2/2] arm64: dts: ti: Add support for the phyCORE-AM67x
From: Nathan Morrisson @ 2026-06-29 22:33 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: afd, sashiko-reviews, linux-arm-kernel, devicetree, linux-kernel,
upstream, w.egorov
In-Reply-To: <20260629223353.1495209-1-nmorrisson@phytec.com>
Add support for the PHYTEC phyCORE-AM67x SoM [1] and the
corresponding phyBOARD-Rigel carrier board [2]. The phyCORE-AM67x SoM
uses the TI AM67x SoC and can come with different sizes and models of
DDR, eMMC, and SPI NOR Flash.
Supported features:
* Audio playback and recording
* CAN
* Debug UART
* eMMC
* Ethernet
* GPIO buttons
* Heartbeat LED
* I2C Current sensor
* I2C EEPROM
* I2C Light sensor
* I2C RTC
* Micro SD card
* SPI NOR flash
* USB
[1] https://www.phytec.com/product/phycore-am67x/
[2] https://www.phytec.com/product/phyboard-am67x-development-kit/
Signed-off-by: Nathan Morrisson <nmorrisson@phytec.com>
Reviewed-by: Andrew Davis <afd@ti.com>
Reviewed-by: Wadim Egorov <w.egorov@phytec.de>
---
Changes in v3:
* Moved j722s.dtsi include to the carrier board dts, which is
consistent with how the SoC dtsi is included for other SoM +
carrier board combinations.
* Remove pcie for now. We seem to have an issue with the external
refclk so I will drop the interface.
arch/arm64/boot/dts/ti/Makefile | 1 +
.../boot/dts/ti/k3-am67-phycore-som.dtsi | 324 +++++++++++++
.../boot/dts/ti/k3-am6754-phyboard-rigel.dts | 431 ++++++++++++++++++
3 files changed, 756 insertions(+)
create mode 100644 arch/arm64/boot/dts/ti/k3-am67-phycore-som.dtsi
create mode 100644 arch/arm64/boot/dts/ti/k3-am6754-phyboard-rigel.dts
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 371f9a043fe5..623ee2369132 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -184,6 +184,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-pcie1-ep.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-usb0-type-a.dtbo
# Boards with J722s SoC
+dtb-$(CONFIG_ARCH_K3) += k3-am6754-phyboard-rigel.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtbo
diff --git a/arch/arm64/boot/dts/ti/k3-am67-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am67-phycore-som.dtsi
new file mode 100644
index 000000000000..bc74c4eef193
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am67-phycore-som.dtsi
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2026 PHYTEC America LLC
+ * Author: Nathan Morrisson <nmorrisson@phytec.com>
+ */
+
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "phytec,am67-phycore-som", "ti,j722s";
+ model = "PHYTEC phyCORE-AM67";
+
+ aliases {
+ ethernet0 = &cpsw_port1;
+ gpio0 = &main_gpio0;
+ mmc0 = &sdhci0;
+ rtc0 = &i2c_som_rtc;
+ rtc1 = &wkup_rtc0;
+ spi0 = &ospi0;
+ };
+
+ memory@80000000 {
+ /* 4G RAM */
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+ <0x00000008 0x80000000 0x00000000 0x80000000>;
+ device_type = "memory";
+ bootph-all;
+ };
+
+ reserved_memory: reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ secure_tfa_ddr: tfa@9e780000 {
+ reg = <0x00 0x9e780000 0x00 0x80000>;
+ no-map;
+ };
+
+ secure_ddr: optee@9e800000 {
+ reg = <0x00 0x9e800000 0x00 0x01800000>;
+ no-map;
+ };
+
+ wkup_r5fss0_core0_dma_memory_region: memory@a0000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa0000000 0x00 0x100000>;
+ no-map;
+ };
+
+ wkup_r5fss0_core0_memory_region: memory@a0100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa0100000 0x00 0xf00000>;
+ no-map;
+ };
+ };
+
+ vcc_5v0_som: regulator-vcc-5v0-som {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_5V0_SOM";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins_default>;
+
+ led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&main_gpio0 13 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ function = LED_FUNCTION_HEARTBEAT;
+ };
+ };
+};
+
+&main_pmx0 {
+ leds_pins_default: leds-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x034, PIN_OUTPUT, 7) /* (K22) OSPI0_CSN2.GPIO0_13 */
+ >;
+ };
+
+ mdio_pins_default: mdio-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AC24) MDIO0_MDC */
+ J722S_IOPAD(0x015c, PIN_INPUT, 0) /* (AD25) MDIO0_MDIO */
+ >;
+ bootph-all;
+ };
+
+ ospi0_pins_default: ospi0-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x000, PIN_OUTPUT, 0) /* (L24) OSPI0_CLK */
+ J722S_IOPAD(0x02c, PIN_OUTPUT, 0) /* (K26) OSPI0_CSn0 */
+ J722S_IOPAD(0x00c, PIN_INPUT, 0) /* (K27) OSPI0_D0 */
+ J722S_IOPAD(0x010, PIN_INPUT, 0) /* (L27) OSPI0_D1 */
+ J722S_IOPAD(0x014, PIN_INPUT, 0) /* (L26) OSPI0_D2 */
+ J722S_IOPAD(0x018, PIN_INPUT, 0) /* (L25) OSPI0_D3 */
+ J722S_IOPAD(0x01c, PIN_INPUT, 0) /* (L21) OSPI0_D4 */
+ J722S_IOPAD(0x020, PIN_INPUT, 0) /* (M26) OSPI0_D5 */
+ J722S_IOPAD(0x024, PIN_INPUT, 0) /* (N27) OSPI0_D6 */
+ J722S_IOPAD(0x028, PIN_INPUT, 0) /* (M27) OSPI0_D7 */
+ J722S_IOPAD(0x008, PIN_INPUT, 0) /* (L22) OSPI0_DQS */
+ J722S_IOPAD(0x038, PIN_INPUT, 7) /* (J22) OSPI0_CSn3.GPIO0_14 */
+ >;
+ bootph-all;
+ };
+
+ pmic_irq_pins_default: pmic-irq-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x030, PIN_INPUT, 7) /* (K23) OSPI0_CSN1.GPIO0_12 */
+ >;
+ };
+
+ rgmii1_pins_default: rgmii1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x014c, PIN_INPUT, 0) /* (AC25) RGMII1_RD0 */
+ J722S_IOPAD(0x0150, PIN_INPUT, 0) /* (AD27) RGMII1_RD1 */
+ J722S_IOPAD(0x0154, PIN_INPUT, 0) /* (AE24) RGMII1_RD2 */
+ J722S_IOPAD(0x0158, PIN_INPUT, 0) /* (AE26) RGMII1_RD3 */
+ J722S_IOPAD(0x0148, PIN_INPUT, 0) /* (AE27) RGMII1_RXC */
+ J722S_IOPAD(0x0144, PIN_INPUT, 0) /* (AD23) RGMII1_RX_CTL */
+ J722S_IOPAD(0x0134, PIN_OUTPUT, 0) /* (AF27) RGMII1_TD0 */
+ J722S_IOPAD(0x0138, PIN_OUTPUT, 0) /* (AE23) RGMII1_TD1 */
+ J722S_IOPAD(0x013c, PIN_OUTPUT, 0) /* (AG25) RGMII1_TD2 */
+ J722S_IOPAD(0x0140, PIN_OUTPUT, 0) /* (AF24) RGMII1_TD3 */
+ J722S_IOPAD(0x0130, PIN_OUTPUT, 0) /* (AG26) RGMII1_TXC */
+ J722S_IOPAD(0x012c, PIN_OUTPUT, 0) /* (AF25) RGMII1_TX_CTL */
+ >;
+ bootph-all;
+ };
+};
+
+&mcu_pmx0 {
+ wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+ pinctrl-single,pins = <
+ J722S_MCU_IOPAD(0x04c, PIN_INPUT_PULLUP, 0) /* (B9) WKUP_I2C0_SCL */
+ J722S_MCU_IOPAD(0x050, PIN_INPUT_PULLUP, 0) /* (D11) WKUP_I2C0_SDA */
+ >;
+ bootph-all;
+ };
+};
+
+&cpsw3g {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii1_pins_default>;
+ bootph-all;
+ status = "okay";
+};
+
+&cpsw3g_mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins_default>;
+ status = "okay";
+
+ cpsw3g_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ tx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ ti,min-output-impedance;
+ };
+};
+
+&cpsw_port1 {
+ phy-mode = "rgmii-id";
+ phy-handle = <&cpsw3g_phy1>;
+ status = "okay";
+};
+
+&ospi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ospi0_pins_default>;
+ bootph-all;
+ status = "okay";
+
+ serial_flash: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <8>;
+ spi-rx-bus-width = <8>;
+ spi-max-frequency = <25000000>;
+ vcc-supply = <&vdd_1v8>;
+ cdns,tshsl-ns = <60>;
+ cdns,tsd2d-ns = <60>;
+ cdns,tchsh-ns = <60>;
+ cdns,tslch-ns = <60>;
+ cdns,read-delay = <0>;
+ };
+};
+
+&sdhci0 {
+ non-removable;
+ bootph-all;
+ ti,driver-strength-ohm = <50>;
+ status = "okay";
+};
+
+&wkup_i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wkup_i2c0_pins_default>;
+ clock-frequency = <400000>;
+ bootph-all;
+ status = "okay";
+
+ pmic@30 {
+ compatible = "ti,tps65219";
+ reg = <0x30>;
+ buck1-supply = <&vcc_5v0_som>;
+ buck2-supply = <&vcc_5v0_som>;
+ buck3-supply = <&vcc_5v0_som>;
+ ldo1-supply = <&vdd_3v3>;
+ ldo2-supply = <&vdd_1v8>;
+ ldo3-supply = <&vdd_3v3>;
+ ldo4-supply = <&vdd_3v3>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_irq_pins_default>;
+ interrupt-parent = <&main_gpio0>;
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ system-power-controller;
+ ti,power-button;
+
+ regulators {
+ vdd_3v3: buck1 {
+ regulator-name = "VDD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd_1v8: buck2 {
+ regulator-name = "VDD_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd_lpddr4: buck3 {
+ regulator-name = "VDD_LPDDR4";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vddshv_sdio: ldo1 {
+ regulator-name = "VDDSHV_SDIO";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-allow-bypass;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd_1v2: ldo2 {
+ regulator-name = "VDD_1V2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdda_1v8_phy: ldo3 {
+ regulator-name = "VDDA_1V8_PHY";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd_1v8_pll: ldo4 {
+ regulator-name = "VDD_1V8_PLL";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+
+ vdd_core: regulator-vdd-core@44 {
+ compatible = "ti,tps62873";
+ reg = <0x44>;
+ bootph-pre-ram;
+ regulator-name = "VDD_CORE";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c32";
+ reg = <0x50>;
+ pagesize = <32>;
+ };
+
+ som_eeprom_opt: eeprom@51 {
+ compatible = "atmel,24c32";
+ reg = <0x51>;
+ pagesize = <32>;
+ };
+
+ i2c_som_rtc: rtc@52 {
+ compatible = "microcrystal,rv3028";
+ reg = <0x52>;
+ };
+};
+
+#include "k3-j722s-ti-ipc-firmware.dtsi"
diff --git a/arch/arm64/boot/dts/ti/k3-am6754-phyboard-rigel.dts b/arch/arm64/boot/dts/ti/k3-am6754-phyboard-rigel.dts
new file mode 100644
index 000000000000..26dcda26061f
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am6754-phyboard-rigel.dts
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2026 PHYTEC America LLC
+ * Author: Nathan Morrisson <nmorrisson@phytec.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "k3-serdes.h"
+#include "k3-j722s.dtsi"
+#include "k3-am67-phycore-som.dtsi"
+
+/ {
+ compatible = "phytec,am6754-phyboard-rigel",
+ "phytec,am67-phycore-som", "ti,j722s";
+ model = "PHYTEC phyBOARD-Rigel AM67";
+
+ aliases {
+ gpio1 = &main_gpio1;
+ mmc1 = &sdhci1;
+ serial2 = &main_uart0;
+ usb0 = &usb0;
+ usb1 = &usb1;
+ };
+
+ can_tc0: can-phy0 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <8000000>;
+ standby-gpios = <&gpio_exp1 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ usb0_connector: connector {
+ compatible = "gpio-usb-b-connector", "usb-b-connector";
+ label = "USB-C";
+ data-role = "dual";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_usbc_power_pins_default>;
+
+ id-gpios = <&main_gpio1 15 GPIO_ACTIVE_HIGH>;
+
+ port {
+ usb0_con: endpoint {
+ remote-endpoint = <&usb0_ep>;
+ };
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+ autorepeat;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys_pins_default>;
+
+ key-home {
+ label = "home";
+ linux,code = <KEY_HOME>;
+ gpios = <&main_gpio1 23 GPIO_ACTIVE_HIGH>;
+ };
+
+ key-menu {
+ label = "menu";
+ linux,code = <KEY_MENU>;
+ gpios = <&gpio_exp1 4 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ vcc_1v8: regulator-vcc-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_3v3_aud: regulator-vcc-3v3-aud {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3_AUD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_3v3_mmc: regulator-vcc-3v3-mmc {
+ /* TPS22963C OUTPUT */
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3_MMC";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_3v3_sw: regulator-vcc-3v3-sw {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3_SW";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_speaker: regulator-vcc-speaker {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_SPEAKER";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,widgets =
+ "Microphone", "Mic Jack",
+ "Headphone", "Headphone Jack",
+ "Line", "Stereo Jack",
+ "Speaker", "L SPKR",
+ "Speaker", "R SPKR";
+ simple-audio-card,routing =
+ "MIC1RP", "Mic Jack",
+ "Mic Jack", "MICBIAS",
+ "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR",
+ "MIC1LM", "Stereo Jack",
+ "MIC1LP", "Stereo Jack",
+ "SPL", "L SPKR",
+ "SPR", "R SPKR";
+ simple-audio-card,name = "phyBOARD-Rigel";
+ simple-audio-card,format = "dsp_b";
+ simple-audio-card,bitclock-master = <&sound_master>;
+ simple-audio-card,frame-master = <&sound_master>;
+ simple-audio-card,bitclock-inversion;
+
+ simple-audio-card,cpu {
+ sound-dai = <&mcasp0>;
+ };
+
+ sound_master: simple-audio-card,codec {
+ sound-dai = <&audio_codec>;
+ clocks = <&audio_refclk1>;
+ };
+ };
+};
+
+&main_pmx0 {
+ audio_ext_refclk1_pins_default: audio-ext-refclk1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0a0, PIN_OUTPUT, 1) /* (N24) GPMC0_WPn.AUDIO_EXT_REFCLK1 */
+ >;
+ };
+
+ gpio_exp0_int_pins_default: gpio-exp0-int-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0054, PIN_INPUT, 7) /* (T21) GPMC0_AD6.GPIO0_21 */
+ >;
+ };
+
+ gpio_exp1_int_pins_default: gpio-exp1-int-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0244, PIN_INPUT, 7) /* (A24) MMC1_SDWP.GPIO1_49 */
+ >;
+ };
+
+ gpio_exp2_int_pins_default: gpio-exp2-int-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0050, PIN_INPUT, 7) /* (T24) GPMC0_AD5.GPIO0_20 */
+ >;
+ };
+
+ gpio_keys_pins_default: gpio-keys-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x01d4, PIN_INPUT, 7) /* (B21) UART0_RTSn.GPIO1_23 */
+ >;
+ };
+
+ main_i2c0_pins_default: main-i2c0-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (D23) I2C0_SCL */
+ J722S_IOPAD(0x01e4, PIN_INPUT_PULLUP, 0) /* (B22) I2C0_SDA */
+ >;
+ bootph-all;
+ };
+
+ main_i2c1_pins_default: main-i2c1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x01e8, PIN_INPUT_PULLUP, 0) /* (C24) I2C1_SCL */
+ J722S_IOPAD(0x01ec, PIN_INPUT_PULLUP, 0) /* (A22) I2C1_SDA */
+ >;
+ bootph-all;
+ };
+
+ main_mcan0_pins_default: main-mcan0-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x1dc, PIN_INPUT, 0) /* (C22) MCAN0_RX */
+ J722S_IOPAD(0x1d8, PIN_OUTPUT, 0) /* (D22) MCAN0_TX */
+ >;
+ };
+
+ main_mcasp0_pins_default: main-mcasp0-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x1a8, PIN_INPUT, 0) /* (C26) MCASP0_AFSX */
+ J722S_IOPAD(0x1a4, PIN_INPUT, 0) /* (D25) MCASP0_ACLKX */
+ J722S_IOPAD(0x198, PIN_OUTPUT, 0) /* (A26) MCASP0_AXR2 */
+ J722S_IOPAD(0x194, PIN_INPUT, 0) /* (A25) MCASP0_AXR3 */
+ >;
+ };
+
+ main_mmc1_pins_default: main-mmc1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x023c, PIN_INPUT, 0) /* (H22) MMC1_CMD */
+ J722S_IOPAD(0x0234, PIN_INPUT, 0) /* (H24) MMC1_CLK */
+ J722S_IOPAD(0x0230, PIN_INPUT, 0) /* (H23) MMC1_DAT0 */
+ J722S_IOPAD(0x022c, PIN_INPUT, 0) /* (H20) MMC1_DAT1 */
+ J722S_IOPAD(0x0228, PIN_INPUT, 0) /* (J23) MMC1_DAT2 */
+ J722S_IOPAD(0x0224, PIN_INPUT, 0) /* (H25) MMC1_DAT3 */
+ J722S_IOPAD(0x0240, PIN_INPUT, 0) /* (B24) MMC1_SDCD */
+ >;
+ bootph-all;
+ };
+
+ main_uart0_pins_default: main-uart0-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x01c8, PIN_INPUT, 0) /* (F19) UART0_RXD */
+ J722S_IOPAD(0x01cc, PIN_OUTPUT, 0) /* (F20) UART0_TXD */
+ >;
+ bootph-all;
+ };
+
+ main_usbc_power_pins_default: main-usbc-power-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x1b4, PIN_INPUT, 7) /* (B20) SPI0_CS0.GPIO1_15 */
+ >;
+ };
+};
+
+&audio_refclk1 {
+ assigned-clock-rates = <25000000>;
+};
+
+&main_i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c0_pins_default>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ veml6030: light-sensor@10 {
+ compatible = "vishay,veml6030";
+ reg = <0x10>;
+ vdd-supply = <&vcc_3v3_sw>;
+ };
+};
+
+&main_i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c1_pins_default>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ audio_codec: audio-codec@18 {
+ compatible = "ti,tlv320aic3110";
+ reg = <0x18>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&audio_ext_refclk1_pins_default>;
+ #sound-dai-cells = <0>;
+ ai31xx-micbias-vg = <2>;
+ reset-gpios = <&gpio_exp1 7 GPIO_ACTIVE_LOW>;
+
+ HPVDD-supply = <&vcc_3v3_aud>;
+ SPRVDD-supply = <&vcc_speaker>;
+ SPLVDD-supply = <&vcc_speaker>;
+ AVDD-supply = <&vcc_3v3_aud>;
+ IOVDD-supply = <&vcc_3v3_aud>;
+ DVDD-supply = <&vcc_1v8>;
+ };
+
+ gpio_exp0: gpio@20 {
+ compatible = "nxp,pcf8574";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_exp0_int_pins_default>;
+ interrupt-parent = <&main_gpio0>;
+ interrupts = <21 IRQ_TYPE_EDGE_FALLING>;
+ gpio-line-names = "CSI3_STROBE", "CSI3_TRIGGER",
+ "CSI3_SHUTTER", "CSI3_OE",
+ "CSI2_STROBE", "CSI2_TRIGGER",
+ "CSI2_SHUTTER", "CSI2_OE";
+ };
+
+ gpio_exp1: gpio@21 {
+ compatible = "nxp,pcf8574";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_exp1_int_pins_default>;
+ interrupt-parent = <&main_gpio1>;
+ interrupts = <49 IRQ_TYPE_EDGE_FALLING>;
+ gpio-line-names = "GPIO0_HDMI_RST", "GPIO1_CAN_nEN",
+ "GPIO2_LED", "GPIO3_MCU_CAN0_nEN",
+ "GPIO4_BUT2", "GPIO5_MCU_CAN1_nEN",
+ "GPIO6_AUDIO_GPIO", "GPIO7_AUDIO_USER_RESET";
+ };
+
+ gpio_exp2: gpio@23 {
+ compatible = "nxp,pcf8574";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_exp2_int_pins_default>;
+ interrupt-parent = <&main_gpio0>;
+ interrupts = <20 IRQ_TYPE_EDGE_FALLING>;
+ gpio-line-names = "CSI1_STROBE", "CSI1_TRIGGER",
+ "CSI1_SHUTTER", "CSI1_OE",
+ "CSI0_STROBE", "CSI0_TRIGGER",
+ "CSI0_SHUTTER", "CSI0_OE";
+ };
+
+ current-sensor@40 {
+ compatible = "ti,ina233";
+ reg = <0x40>;
+ shunt-resistor = <18000>;
+ };
+
+ eeprom@51 {
+ compatible = "atmel,24c02";
+ reg = <0x51>;
+ pagesize = <16>;
+ };
+};
+
+&main_mcan0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan0_pins_default>;
+ phys = <&can_tc0>;
+ status = "okay";
+};
+
+&main_uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_uart0_pins_default>;
+ bootph-all;
+ status = "okay";
+};
+
+&mcasp0 {
+ #sound-dai-cells = <0>;
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcasp0_pins_default>;
+ tdm-slots = <2>;
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 0 0 1 2
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ >;
+ status = "okay";
+};
+
+&sdhci1 {
+ /* SD/MMC */
+ vmmc-supply = <&vcc_3v3_mmc>;
+ vqmmc-supply = <&vddshv_sdio>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mmc1_pins_default>;
+ disable-wp;
+ no-1-8-v;
+ bootph-all;
+ status = "okay";
+};
+
+&serdes_ln_ctrl {
+ idle-states = <J722S_SERDES0_LANE0_USB>,
+ <J722S_SERDES1_LANE0_PCIE0_LANE0>;
+};
+
+&serdes0 {
+ status = "okay";
+
+ serdes0_usb_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <1>;
+ #phy-cells = <0>;
+ cdns,phy-type = <PHY_TYPE_USB3>;
+ resets = <&serdes_wiz0 1>;
+ };
+};
+
+&serdes_wiz0 {
+ status = "okay";
+};
+
+&usbss0 {
+ ti,vbus-divider;
+ status = "okay";
+};
+
+&usb0 {
+ dr_mode = "otg";
+ usb-role-switch;
+ maximum-speed = "high-speed";
+
+ port {
+ usb0_ep: endpoint {
+ remote-endpoint = <&usb0_con>;
+ };
+ };
+};
+
+&usbss1 {
+ ti,vbus-divider;
+ status = "okay";
+};
+
+&usb1 {
+ dr_mode = "host";
+ phys = <&serdes0_usb_link>;
+ phy-names = "cdns3,usb3-phy";
+ maximum-speed = "super-speed";
+};
--
2.43.0
^ permalink raw reply related
* [PATCH v3 1/2] dt-bindings: arm: ti: Add bindings for PHYTEC AM67x based hardware
From: Nathan Morrisson @ 2026-06-29 22:33 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: afd, sashiko-reviews, linux-arm-kernel, devicetree, linux-kernel,
upstream, w.egorov
Add device tree bindings for the AM67x based phyCORE-AM67x SoM and
phyBOARD-Rigel.
Signed-off-by: Nathan Morrisson <nmorrisson@phytec.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
---
No changes in v3
Documentation/devicetree/bindings/arm/ti/k3.yaml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
index 69b5441cbf1a..ae47190d1f82 100644
--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
+++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -222,6 +222,13 @@ properties:
- ti,j722s-evm
- const: ti,j722s
+ - description: K3 AM67 SoC PHYTEC phyBOARD-Rigel
+ items:
+ - enum:
+ - phytec,am6754-phyboard-rigel
+ - const: phytec,am67-phycore-som
+ - const: ti,j722s
+
- description: K3 J742S2 SoC
items:
- enum:
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] ARM: imx: Drop obsolte stuff from common.h
From: Frank Li @ 2026-06-29 22:23 UTC (permalink / raw)
To: Uwe Kleine-König (The Capable Hub)
Cc: Sascha Hauer, Frank Li, Pengutronix Kernel Team, Fabio Estevam,
linux-arm-kernel, imx
In-Reply-To: <akLlvHMcVpXDsS9l@monoceros>
On Mon, Jun 29, 2026 at 11:39:39PM +0200, Uwe Kleine-König (The Capable Hub) wrote:
> Hello Frank,
>
> On Mon, Jun 29, 2026 at 05:12:07PM -0400, Frank.Li@oss.nxp.com wrote:
> > From: Frank Li <Frank.Li@nxp.com>
> >
> > On Tue, 23 Jun 2026 12:45:57 +0200, Uwe Kleine-König (The Capable Hub) wrote:
> > > i.MX21 (and thus imx21_init_early()) is gone since v5.10-rc1 (commit
> > > 4b563a066611 ("ARM: imx: Remove imx21 support")).
> > >
> > > The init_irq() functions are gone since v5.12-rc5 (commit e2c1b0ff38c9
> > > ("ARM: imx: avic: Convert to using IRQCHIP_DECLARE")).
> > >
> > > And mxc_device_init() was removed for v5.10-rc1 (in commit 8485adf17a15
> > > ("ARM: imx: Remove imx device directory")).
> > >
> > > [...]
> >
> > Applied, thanks!
> >
> > [1/1] ARM: imx: Drop obsolte stuff from common.h
> ^
> There is an 'e' missing ---' (i.e. s/obsolte/obsolete/).
>
> If you want to fix-up that's great, if not, I can live with the shame
> :-)
Fixed it.
Frank
>
> Best regards
> Uwe
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox