* Re: [PATCH v5 1/2] dt-bindings: phy: qcom: Add CSI2 C-PHY/DPHY schema
From: Dmitry Baryshkov @ 2026-03-29 10:54 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Vladimir Zapolskiy, Bryan O'Donoghue, Vinod Koul,
Kishon Vijay Abraham I, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Neil Armstrong, linux-arm-msm, linux-phy,
linux-media, devicetree, linux-kernel
In-Reply-To: <0322e0b3-bce8-4415-90b2-d14445986e23@kernel.org>
On Fri, Mar 27, 2026 at 11:40:51PM +0000, Bryan O'Donoghue wrote:
> On 27/03/2026 23:23, Dmitry Baryshkov wrote:
> > On Sat, Mar 28, 2026 at 01:12:22AM +0200, Vladimir Zapolskiy wrote:
> > > On 3/28/26 00:29, Bryan O'Donoghue wrote:
> > > > On 27/03/2026 20:51, Dmitry Baryshkov wrote:
> > > > > > That's just not true. If you read the camx source code you can see
> > > > > > split/combo mode 2+1 1+1 data/clock mode requires special programming of the
> > > > > > PHY to support.
> > > > > This needs to be identified from the data-lanes / clock-lanes topology.
> > > > > And once you do that, there would be (probably) no difference in the
> > > > > hardware definition.
> > > > >
> > > > >
> > > > > In other words, I'd also ask to drop this mode from the DT. This
> > > > > infromation can and should be deduced from other, already-defined
> > > > > properties.
> > > >
> > > > It still needs to be communicated to the PHY from the controller,
> > > > however that is not a problem I am trying to solve now.
> > > >
> > > > If I can't get consensus for PHY_QCOM_CSI2_MODE_SPLIT_DPHY then so be it.
> > > >
> > > > I'll aim for DPHY only and we can come back to this topic when someone
> > > > actually tries to enable it.
> > > >
> > >
> > > DPHY may be the only supported phy type in the driver, it does not matter
> > > at this point, however it's totally essential to cover the called by you
> > > 'split mode' right from the beginning in the renewed device tree binding
> > > descriptions of CAMSS IPs to progress further.
> >
> > Okay. How would we describe that there are two sensors connected to the
> > single PHY anyway? How would it be described with the current bindings?
> >
> > --
> > With best wishes
> > Dmitry
>
> Assuming you add endpoints to the PHY i.e. that is what Neil appears to be
> asking for and I personally am _fine_ with that, then it should just be
>
> port@0
> port@1
>
> if port@1 exists, you know you are in split-phy mode.
>
> Its actually straight forward enough, really. To be clear though I can write
> that yaml - the _most_ support I'm willing to put into the PHY code is to
> detect the port@1 and say "nope not supported yet", since like CPHY its not.
SGTM. But let's define the schema for those usecases.
>
> ---
> bod
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH] arm64: dts: qcom: Move board nodes to common DTSI
From: Dmitry Baryshkov @ 2026-03-29 10:57 UTC (permalink / raw)
To: Gopikrishna Garmidi
Cc: Krzysztof Kozlowski, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-arm-msm, devicetree,
linux-kernel, sibi.sankar, rajendra.nayak
In-Reply-To: <83c78333-4db9-4943-b90f-164981bb68d8@oss.qualcomm.com>
On Fri, Mar 27, 2026 at 06:16:59PM +0530, Gopikrishna Garmidi wrote:
>
>
> On 3/26/2026 7:55 PM, Krzysztof Kozlowski wrote:
> > On 26/03/2026 15:21, Gopikrishna Garmidi wrote:
> > > The display, peripherals (touchpad/touchscreen/keypad), usb and their
> > > dependent device nodes are common to both Glymur and Mahua CRDs,
> > > so move them from glymur-crd.dts to glymur-crd.dtsi to enable code
> > > reuse.
> > >
> >
> > Same questions as for earlier tries (why this has to be repeated?), e.g.
> > x1-crd: Please describe here what is the actual common hardware. In
> > terms of physical hardware, not what you want to share.
> >
>
> Hi krzysztof,
>
> Thanks for the review,
>
> Will update the commit message in the next re-spin.
Before you respin, you can actually respond to the question. Do Glymur
and Mahua CRD actually share those devices (in case of USB that would
mean having the same baseboard with different SoCs being wired) or is it
just "oh, this looks similar enough, let's create a common file".
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH v4 1/2] dt-bindings: sram: document glymur as compatible
From: Dmitry Baryshkov @ 2026-03-29 11:05 UTC (permalink / raw)
To: Ananthu C V
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
Konrad Dybcio, devicetree, linux-kernel, linux-arm-msm
In-Reply-To: <20260327-glymur-imem-v4-1-8fe0f20ad9fd@oss.qualcomm.com>
On Fri, Mar 27, 2026 at 03:24:35AM -0700, Ananthu C V wrote:
> Add compatible for Qualcomm's glymur IMEM, a block of sram which
> can fall back to mmio-sram.
>
> Acked-by: Rob Herring (Arm) <robh@kernel.org>
> Signed-off-by: Ananthu C V <ananthu.cv@oss.qualcomm.com>
> ---
> Documentation/devicetree/bindings/sram/sram.yaml | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/sram/sram.yaml b/Documentation/devicetree/bindings/sram/sram.yaml
> index c451140962c8..bd62711dc630 100644
> --- a/Documentation/devicetree/bindings/sram/sram.yaml
> +++ b/Documentation/devicetree/bindings/sram/sram.yaml
> @@ -34,6 +34,7 @@ properties:
> - nvidia,tegra186-sysram
> - nvidia,tegra194-sysram
> - nvidia,tegra234-sysram
> + - qcom,glymur-imem
Is it different from the Kaanapali one?
> - qcom,kaanapali-imem
> - qcom,rpm-msg-ram
> - rockchip,rk3288-pmu-sram
>
> --
> 2.43.0
>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH 2/2] arm64: dts: qcom: monaco-evk: enable UART6 for robot expansion board
From: Dmitry Baryshkov @ 2026-03-29 11:08 UTC (permalink / raw)
To: Canfeng Zhuang
Cc: konradybcio, andersson, robh, krzk+dt, conor+dt, linux-arm-msm,
devicetree, linux-arm-kernel
In-Reply-To: <20260327083101.1343613-3-canfeng.zhuang@oss.qualcomm.com>
On Fri, Mar 27, 2026 at 04:31:01PM +0800, Canfeng Zhuang wrote:
> The monaco-evk mezzanine connector supports a robot expansion board that
> requires UART6, which is currently disabled. This prevents the expansion
> board from exchanging data and control commands.
>
> Enable UART6 and assign the serial2 alias to provide stable device
> enumeration for the expansion board.
>
> Signed-off-by: Canfeng Zhuang <canfeng.zhuang@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/monaco-evk.dts | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts
> index 565418b86b2a..0b26861eac02 100644
> --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts
> +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts
> @@ -21,6 +21,7 @@ aliases {
> ethernet0 = ðernet0;
> i2c1 = &i2c1;
> serial0 = &uart7;
> + serial2 = &uart6;
What happened to serial1?
> };
>
> chosen {
--
With best wishes
Dmitry
^ permalink raw reply
* [PATCH] arm64: dts: allwinner: enable h616 timer support
From: Michal Piekos @ 2026-03-29 11:43 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland
Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel,
Michal Piekos
Add support for timer by reusing existing sun4i timer driver.
H616 timer is compatible with earlier sunxi timer variants and provides
both clocksource and clockevent functionality. It runs from 24 MHz
oscillator. It can serve as broadcast clockevent for wake up from idle
states.
Tested on Orange Pi Zero 3:
- timer is registered as clocksource:
- switching clocksource at runtime works
- timer operates as a broadcast clockevent device
- no regression observed compared to arch_sys_counter
Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
---
Test results:
Clocksource switching:
cat /sys/devices/system/clocksource/clocksource0/available_clocksource
arch_sys_counter timer
echo timer > /sys/devices/system/clocksource/clocksource0/current_clocksource
[ 5031.105997] clocksource: Switched to clocksource timer
Clockevent configuration:
cat /proc/timer_list
...
Tick Device: mode: 1
Broadcast device
Clock Event Device: sun4i_tick
max_delta_ns: 178956969070
min_delta_ns: 1000
mult: 51539608
shift: 31
mode: 1
next_event: 9223372036854775807 nsecs
set_next_event: sun4i_clkevt_next_event
shutdown: sun4i_clkevt_shutdown
periodic: sun4i_clkevt_set_periodic
oneshot: sun4i_clkevt_set_oneshot
resume: sun4i_clkevt_shutdown
event_handler: tick_handle_oneshot_broadcast
...
Cyclictest measurements:
Dominated by system scheduler latency and do not reflect clocksource
precision.
---
arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index 8d1110c14bad..bf054869e78b 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -228,6 +228,15 @@ cpu_speed_grade: cpu-speed-grade@0 {
};
};
+ timer0: timer@3009000 {
+ compatible = "allwinner,sun50i-h616-timer",
+ "allwinner,sun8i-a23-timer";
+ reg = <0x03009000 0xa0>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc24M>;
+ };
+
watchdog: watchdog@30090a0 {
compatible = "allwinner,sun50i-h616-wdt",
"allwinner,sun6i-a31-wdt";
---
base-commit: be762d8b6dd7efacb61937d20f8475db8f207655
change-id: 20260328-h616-timer-046e6ac3549e
Best regards,
--
Michal Piekos <michal.piekos@mmpsystems.pl>
^ permalink raw reply related
* Re: [PATCH] arm64: dts: allwinner: enable h616 timer support
From: Jernej Škrabec @ 2026-03-29 11:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
Samuel Holland, Michal Piekos
Cc: devicetree, linux-arm-kernel, linux-sunxi, linux-kernel,
Michal Piekos
In-Reply-To: <20260329-h616-timer-v1-1-5966d0420a66@mmpsystems.pl>
Dne nedelja, 29. marec 2026 ob 13:43:04 Srednjeevropski poletni čas je Michal Piekos napisal(a):
> Add support for timer by reusing existing sun4i timer driver.
>
> H616 timer is compatible with earlier sunxi timer variants and provides
> both clocksource and clockevent functionality. It runs from 24 MHz
> oscillator. It can serve as broadcast clockevent for wake up from idle
> states.
>
> Tested on Orange Pi Zero 3:
> - timer is registered as clocksource:
> - switching clocksource at runtime works
> - timer operates as a broadcast clockevent device
> - no regression observed compared to arch_sys_counter
>
> Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
> ---
> Test results:
>
> Clocksource switching:
> cat /sys/devices/system/clocksource/clocksource0/available_clocksource
> arch_sys_counter timer
> echo timer > /sys/devices/system/clocksource/clocksource0/current_clocksource
> [ 5031.105997] clocksource: Switched to clocksource timer
>
> Clockevent configuration:
> cat /proc/timer_list
> ...
> Tick Device: mode: 1
> Broadcast device
> Clock Event Device: sun4i_tick
> max_delta_ns: 178956969070
> min_delta_ns: 1000
> mult: 51539608
> shift: 31
> mode: 1
> next_event: 9223372036854775807 nsecs
> set_next_event: sun4i_clkevt_next_event
> shutdown: sun4i_clkevt_shutdown
> periodic: sun4i_clkevt_set_periodic
> oneshot: sun4i_clkevt_set_oneshot
> resume: sun4i_clkevt_shutdown
> event_handler: tick_handle_oneshot_broadcast
> ...
>
> Cyclictest measurements:
> Dominated by system scheduler latency and do not reflect clocksource
> precision.
> ---
> arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> index 8d1110c14bad..bf054869e78b 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> @@ -228,6 +228,15 @@ cpu_speed_grade: cpu-speed-grade@0 {
> };
> };
>
> + timer0: timer@3009000 {
> + compatible = "allwinner,sun50i-h616-timer",
> + "allwinner,sun8i-a23-timer";
You have to add above combo to DT bindings.
Best regards,
Jernej
> + reg = <0x03009000 0xa0>;
> + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&osc24M>;
> + };
> +
> watchdog: watchdog@30090a0 {
> compatible = "allwinner,sun50i-h616-wdt",
> "allwinner,sun6i-a31-wdt";
>
> ---
> base-commit: be762d8b6dd7efacb61937d20f8475db8f207655
> change-id: 20260328-h616-timer-046e6ac3549e
>
> Best regards,
>
^ permalink raw reply
* Re: [PATCH v4 1/8] mmc: sdhci-of-k1: enable essential clock, infrastructure for SD operation
From: Vincent Legoll @ 2026-03-29 11:53 UTC (permalink / raw)
To: Iker Pedrosa
Cc: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Michael Opdenacker,
Javier Martinez Canillas, linux-mmc, devicetree, linux-riscv,
spacemit, linux-kernel, Anand Moon, Trevor Gamblin
In-Reply-To: <55c580a0-61cd-435e-bff0-f5f54cbe6948@online.fr>
On 3/29/26 11:20, Vincent Legoll wrote:
> I applied this series on top of
> cbfffcca2bf0622b601b7eaf477aa29035169184 (linux mainline from
> yesterday) and successfully booted the resulting kernel from an SD
> card on an OrangePi-RV2 (with the vendor u-boot from the SPI flash).
>
> So if you want, you can add my: Tested-by: Vincent Legoll
> <legoll@online.fr> # OrangePi-RV2 to the relevant patches from this
> series Thanks Regards
Same for series applied on next-20260327:
Tested-by: Vincent Legoll <legoll@online.fr> # OrangePi-RV2
P.S.: Sorry for the formatting, struggling with thunderbird.
^ permalink raw reply
* Re: [PATCH 2/2] iio: adc: qcom-pm8xxx-xoadc: add support for reading channel labels
From: Andy Shevchenko @ 2026-03-29 11:54 UTC (permalink / raw)
To: Antony Kurniawan Soemardi
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, linux-arm-msm, devicetree, linux-kernel,
linux-iio, phone-devel
In-Reply-To: <c8e6166f-e9fc-430e-b290-a97c2aae2b31@smankusors.com>
On Fri, Mar 27, 2026 at 07:05:04PM +0000, Antony Kurniawan Soemardi wrote:
> On 3/27/2026 2:04 AM, Andy Shevchenko wrote:
> > On Thu, Mar 26, 2026 at 12:00:52PM +0000, Antony Kurniawan Soemardi wrote:
> > > On 3/26/2026 5:18 PM, Andy Shevchenko wrote:
...
> > > > > + if (!ch) {
> > > > > + dev_err(adc->dev, "no such channel %lu\n", chan->address);
> > > > > + return -EINVAL;
> > > > > + }
> > > >
> > > > Isn't it a dead code? Also poisoning dmesg with this recurrent message is
> > > > not good idea to begin with (the user space will have a door to flood it,
> > > > which might be considered as an assistance to hackers to clear immediate
> > > > logs after a successful attack).
> > >
> > > Good point about the successful attack hint! I was copying the existing
> > > code from pm8xxx_read_raw. Do you think those checks are unnecessary for
> > > pm8xxx_read_raw as well?
> >
> > Yes, I think they are not as the returned code should be enough to identify
> > the problem. (For no such channel I would rather see -ENOENT, but we can't
> > simply replace that in the existing code as it's part of ABI.)
>
> Just to re-clarify, do you mean for both pm8xxx_read_label &
> pm8xxx_read_raw:
> 1. if the check fails, it should only return -EINVAL without any
> logging; or
> 2. remove the checks because there's no way it's not found?
The first one. And yeah, -EINVAL in the both cases for the sake of consistency.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH] arm64: dts: allwinner: enable h616 timer support
From: Michal Piekos @ 2026-03-29 12:07 UTC (permalink / raw)
To: Jernej Škrabec
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
Samuel Holland, devicetree, linux-arm-kernel, linux-sunxi,
linux-kernel
In-Reply-To: <5977334.DvuYhMxLoT@jernej-laptop>
On Sun, Mar 29, 2026 at 01:53:45PM +0200, Jernej Škrabec wrote:
> Dne nedelja, 29. marec 2026 ob 13:43:04 Srednjeevropski poletni čas je Michal Piekos napisal(a):
> > Add support for timer by reusing existing sun4i timer driver.
> >
> > H616 timer is compatible with earlier sunxi timer variants and provides
> > both clocksource and clockevent functionality. It runs from 24 MHz
> > oscillator. It can serve as broadcast clockevent for wake up from idle
> > states.
> >
> > Tested on Orange Pi Zero 3:
> > - timer is registered as clocksource:
> > - switching clocksource at runtime works
> > - timer operates as a broadcast clockevent device
> > - no regression observed compared to arch_sys_counter
> >
> > Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
> > ---
> > Test results:
> >
> > Clocksource switching:
> > cat /sys/devices/system/clocksource/clocksource0/available_clocksource
> > arch_sys_counter timer
> > echo timer > /sys/devices/system/clocksource/clocksource0/current_clocksource
> > [ 5031.105997] clocksource: Switched to clocksource timer
> >
> > Clockevent configuration:
> > cat /proc/timer_list
> > ...
> > Tick Device: mode: 1
> > Broadcast device
> > Clock Event Device: sun4i_tick
> > max_delta_ns: 178956969070
> > min_delta_ns: 1000
> > mult: 51539608
> > shift: 31
> > mode: 1
> > next_event: 9223372036854775807 nsecs
> > set_next_event: sun4i_clkevt_next_event
> > shutdown: sun4i_clkevt_shutdown
> > periodic: sun4i_clkevt_set_periodic
> > oneshot: sun4i_clkevt_set_oneshot
> > resume: sun4i_clkevt_shutdown
> > event_handler: tick_handle_oneshot_broadcast
> > ...
> >
> > Cyclictest measurements:
> > Dominated by system scheduler latency and do not reflect clocksource
> > precision.
> > ---
> > arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 9 +++++++++
> > 1 file changed, 9 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> > index 8d1110c14bad..bf054869e78b 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> > @@ -228,6 +228,15 @@ cpu_speed_grade: cpu-speed-grade@0 {
> > };
> > };
> >
> > + timer0: timer@3009000 {
> > + compatible = "allwinner,sun50i-h616-timer",
> > + "allwinner,sun8i-a23-timer";
>
> You have to add above combo to DT bindings.
>
> Best regards,
> Jernej
Not sure I understand your comment correctly but binding for h616 is already
there:
Documentation/devicetree/bindings/timer/allwinner,sun4i-a10-timer.yaml:21-27
- items:
- enum:
- allwinner,sun20i-d1-timer
- allwinner,sun50i-a64-timer
- allwinner,sun50i-h6-timer
- allwinner,sun50i-h616-timer
- const: allwinner,sun8i-a23-timer
BR
Michal
>
> > + reg = <0x03009000 0xa0>;
> > + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&osc24M>;
> > + };
> > +
> > watchdog: watchdog@30090a0 {
> > compatible = "allwinner,sun50i-h616-wdt",
> > "allwinner,sun6i-a31-wdt";
> >
> > ---
> > base-commit: be762d8b6dd7efacb61937d20f8475db8f207655
> > change-id: 20260328-h616-timer-046e6ac3549e
> >
> > Best regards,
> >
>
>
>
>
^ permalink raw reply
* [PATCH v3 0/2] dt-bindings: thermal: st,thermal-spear1340: convert to dtschema
From: Gopi Krishna Menon @ 2026-03-29 12:34 UTC (permalink / raw)
To: rafael, daniel.lezcano, rui.zhang, lukasz.luba, robh, krzk+dt,
vireshk, conor+dt
Cc: Gopi Krishna Menon, linux-pm, devicetree, linux-kernel,
linux-arm-kernel, soc, daniel.baluta, simona.toaca, d-gole,
m-chawdhry
This patch series converts SPEAr Thermal Sensor bindings to DT schema
and removes the thermal_flags property from spear13xx.dtsi.
Changes since v2:
- Reword the commit message and subject to correct explanation in patch 2
- No changes in patch 1
Changes since v1:
- Changed unevaluatedProperties to additionalProperties in the binding
- Reword the commit message and subject in the second patch
Note:
* This patch is part of the GSoC2026 application process for device tree bindings conversions
* https://github.com/LinuxFoundationGSoC/ProjectIdeas/wiki/GSoC-2026-Device-Tree-Bindings
Gopi Krishna Menon (2):
dt-bindings: thermal: st,thermal-spear1340: convert to dtschema
ARM: dts: st: spear: remove undocumented thermal_flags property
.../bindings/thermal/spear-thermal.txt | 14 --------
.../thermal/st,thermal-spear1340.yaml | 36 +++++++++++++++++++
arch/arm/boot/dts/st/spear13xx.dtsi | 1 -
3 files changed, 36 insertions(+), 15 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/thermal/spear-thermal.txt
create mode 100644 Documentation/devicetree/bindings/thermal/st,thermal-spear1340.yaml
--
2.52.0
^ permalink raw reply
* [PATCH v3 1/2] dt-bindings: thermal: st,thermal-spear1340: convert to dtschema
From: Gopi Krishna Menon @ 2026-03-29 12:34 UTC (permalink / raw)
To: rafael, daniel.lezcano, rui.zhang, lukasz.luba, robh, krzk+dt,
vireshk, conor+dt
Cc: Gopi Krishna Menon, linux-pm, devicetree, linux-kernel,
linux-arm-kernel, soc, daniel.baluta, simona.toaca, d-gole,
m-chawdhry, Krzysztof Kozlowski
In-Reply-To: <20260329123449.309814-1-krishnagopi487@gmail.com>
Convert the SPEAr Thermal Sensor bindings to DT schema.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Gopi Krishna Menon <krishnagopi487@gmail.com>
---
Changes since v2:
- No changes
Changes since v1:
- Changed unevaluatedProperties to additionalProperties in the binding
- Reword the commit message and subject in the second patch
Note:
* This patch is part of the GSoC2026 application process for device tree bindings conversions
* https://github.com/LinuxFoundationGSoC/ProjectIdeas/wiki/GSoC-2026-Device-Tree-Bindings
.../bindings/thermal/spear-thermal.txt | 14 --------
.../thermal/st,thermal-spear1340.yaml | 36 +++++++++++++++++++
2 files changed, 36 insertions(+), 14 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/thermal/spear-thermal.txt
create mode 100644 Documentation/devicetree/bindings/thermal/st,thermal-spear1340.yaml
diff --git a/Documentation/devicetree/bindings/thermal/spear-thermal.txt b/Documentation/devicetree/bindings/thermal/spear-thermal.txt
deleted file mode 100644
index 93e3b67c102d..000000000000
--- a/Documentation/devicetree/bindings/thermal/spear-thermal.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-* SPEAr Thermal
-
-Required properties:
-- compatible : "st,thermal-spear1340"
-- reg : Address range of the thermal registers
-- st,thermal-flags: flags used to enable thermal sensor
-
-Example:
-
- thermal@fc000000 {
- compatible = "st,thermal-spear1340";
- reg = <0xfc000000 0x1000>;
- st,thermal-flags = <0x7000>;
- };
diff --git a/Documentation/devicetree/bindings/thermal/st,thermal-spear1340.yaml b/Documentation/devicetree/bindings/thermal/st,thermal-spear1340.yaml
new file mode 100644
index 000000000000..e3462a974691
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/st,thermal-spear1340.yaml
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/st,thermal-spear1340.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SPEAr Thermal Sensor
+
+maintainers:
+ - Viresh Kumar <vireshk@kernel.org>
+
+properties:
+ compatible:
+ const: st,thermal-spear1340
+
+ reg:
+ maxItems: 1
+
+ st,thermal-flags:
+ description: flags used to enable thermal sensor
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+required:
+ - compatible
+ - reg
+ - st,thermal-flags
+
+additionalProperties: false
+
+examples:
+ - |
+ thermal@fc000000 {
+ compatible = "st,thermal-spear1340";
+ reg = <0xfc000000 0x1000>;
+ st,thermal-flags = <0x7000>;
+ };
--
2.52.0
^ permalink raw reply related
* [PATCH v3 2/2] ARM: dts: st: spear: remove undocumented thermal_flags property
From: Gopi Krishna Menon @ 2026-03-29 12:34 UTC (permalink / raw)
To: rafael, daniel.lezcano, rui.zhang, lukasz.luba, robh, krzk+dt,
vireshk, conor+dt
Cc: Gopi Krishna Menon, linux-pm, devicetree, linux-kernel,
linux-arm-kernel, soc, daniel.baluta, simona.toaca, d-gole,
m-chawdhry
In-Reply-To: <20260329123449.309814-1-krishnagopi487@gmail.com>
spear13xx.dtsi defines a thermal_flags property in spear thermal sensor
node which is both unused in kernel and undocumented in spear thermal
sensor's binding.
There were no dtbs_check warnings associated with this property as the
underlying spear thermal binding was not converted to DTSchema.
Most likely st,thermal-flags is a misspelling of thermal_flags in
spear13xx.dtsi. Since both st/spear1310.dtsi and st/spear1340.dtsi
define st,thermal-flags property in spear thermal sensor node, we can
safely remove this property from spear13xx.dtsi.
Signed-off-by: Gopi Krishna Menon <krishnagopi487@gmail.com>
---
Changes since v2:
- Reword the commit message and subject to correct explanation in patch 2
Changes since v1:
- Changed unevaluatedProperties to additionalProperties in the binding
- Reword the commit message and subject in the second patch
Note:
* This patch is part of the GSoC2026 application process for device tree bindings conversions
* https://github.com/LinuxFoundationGSoC/ProjectIdeas/wiki/GSoC-2026-Device-Tree-Bindings
arch/arm/boot/dts/st/spear13xx.dtsi | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm/boot/dts/st/spear13xx.dtsi b/arch/arm/boot/dts/st/spear13xx.dtsi
index 159e941708ca..0bb88f2d4ef5 100644
--- a/arch/arm/boot/dts/st/spear13xx.dtsi
+++ b/arch/arm/boot/dts/st/spear13xx.dtsi
@@ -332,7 +332,6 @@ wdt@ec800620 {
thermal@e07008c4 {
compatible = "st,thermal-spear1340";
reg = <0xe07008c4 0x4>;
- thermal_flags = <0x7000>;
};
};
};
--
2.52.0
^ permalink raw reply related
* [PATCH 2/2 v2] devicetree: spi: add spi-mosi-idle-low property support
From: charles-antoine.couret @ 2026-03-29 12:58 UTC (permalink / raw)
To: broonie, robh, krzk+dt, conor+dt
Cc: linux-spi, devicetree, linux-kernel, Charles-Antoine Couret
From: Charles-Antoine Couret <charles-antoine.couret@mind.be>
This flag means that device requires the MOSI line to be low
when it's in idle state.
Signed-off-by: Charles-Antoine Couret <charles-antoine.couret@mind.be>
---
Documentation/devicetree/bindings/spi/spi-controller.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml
index 3b8e990e30c4..5f5b143cb27b 100644
--- a/Documentation/devicetree/bindings/spi/spi-controller.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml
@@ -132,6 +132,11 @@ patternProperties:
description:
The device requires inverse clock polarity (CPOL) mode.
+ spi-mosi-idle-low:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description:
+ The device requires the MOSI line to be low when it's in idle state.
+
required:
- compatible
- reg
--
2.53.0
^ permalink raw reply related
* [PATCH 0/3] arm64: dts: imx8m: Correct PAD settings for PMIC_nINT (2nd part)
From: Peng Fan (OSS) @ 2026-03-29 13:00 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Shawn Guo,
Himanshu Bhavani, Alexander Stein
Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux, Peng Fan
There was a patchset for i.MX8MP [1], but after further check,
i.MX8MM/N were missed, there are three boards that might also has
interrupt storm issue. I not have the boards, per NXP board design
, PMIC_nINT requires CPU internal pull up, I think most vendors will
follow NXP design. So updates the i.MX8MM/N boards, but I not have
the boards for testing. If board owners would give a test, that would
be great.
[1] https://lore.kernel.org/all/20260326-imx8mp-dts-fix-v2-v2-0-62c4ce727448@nxp.com/
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Peng Fan (3):
arm64: dts: imx8mm-emtop-som: Correct PAD settings for PMIC_nINT
arm64: dts: imx8mn-tqma8mqnl: Correct PAD settings for PMIC_nINT
arm64: dts: imx8mm-tqma8mqml: Correct PAD settings for PMIC_nINT
arch/arm64/boot/dts/freescale/imx8mm-emtop-som.dtsi | 4 ++--
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi | 2 +-
arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
---
base-commit: 3b058d1aeeeff27a7289529c4944291613b364e9
change-id: 20260329-imx8m-regulator-4e2e3f1b6ed5
Best regards,
--
Peng Fan <peng.fan@nxp.com>
^ permalink raw reply
* [PATCH 1/3] arm64: dts: imx8mm-emtop-som: Correct PAD settings for PMIC_nINT
From: Peng Fan (OSS) @ 2026-03-29 13:00 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Shawn Guo,
Himanshu Bhavani, Alexander Stein
Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux, Peng Fan
In-Reply-To: <20260329-imx8m-regulator-v1-0-802c0ec507cc@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
With commit 5d0efaf47ee90 ("regulator: pca9450: Correct interrupt type"),
there might be interrupt storm for this board. Need to set PAD PUE and PU
together to make pull up work properly.
While at here, also correct interrupt type as IRQ_TYPE_LEVEL_LOW.
Fixes: cbd3ef64eb9d1 ("arm64: dts: Add support for Emtop SoM & Baseboard")
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8mm-emtop-som.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-emtop-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-emtop-som.dtsi
index 67d22d3768aa8ae7343cffeebcfdde89ed25cc2d..507d1824d99d99b1f795b14aea538444c9476f65 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-emtop-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-emtop-som.dtsi
@@ -60,7 +60,7 @@ pmic@25 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pmic>;
interrupt-parent = <&gpio1>;
- interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
regulators {
buck1: BUCK1 {
@@ -194,7 +194,7 @@ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
pinctrl_pmic: emtop-pmic-grp {
fsl,pins = <
- MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41
+ MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x141
>;
};
--
2.37.1
^ permalink raw reply related
* [PATCH 2/3] arm64: dts: imx8mn-tqma8mqnl: Correct PAD settings for PMIC_nINT
From: Peng Fan (OSS) @ 2026-03-29 13:00 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Shawn Guo,
Himanshu Bhavani, Alexander Stein
Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux, Peng Fan
In-Reply-To: <20260329-imx8m-regulator-v1-0-802c0ec507cc@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
With commit 5d0efaf47ee90 ("regulator: pca9450: Correct interrupt type"),
there might be interrupt storm for this board. Need to set PAD PUE and PU
together to make pull up work properly.
Fixes: 3e56e354db6d3 ("arm64: dts: freescale: add initial device tree for TQMa8MQNL with i.MX8MN")
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
index 31a3ca137e63640a2387d3497274f10a6b8c6766..48a687926aa1b88a3d8bef25ff97bebec3777b00 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
@@ -283,7 +283,7 @@ pinctrl_i2c1_gpio: i2c1gpiogrp {
};
pinctrl_pmic: pmicgrp {
- fsl,pins = <MX8MN_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x84>;
+ fsl,pins = <MX8MN_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x1c4>;
};
pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
--
2.37.1
^ permalink raw reply related
* [PATCH 3/3] arm64: dts: imx8mm-tqma8mqml: Correct PAD settings for PMIC_nINT
From: Peng Fan (OSS) @ 2026-03-29 13:00 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Shawn Guo,
Himanshu Bhavani, Alexander Stein
Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux, Peng Fan
In-Reply-To: <20260329-imx8m-regulator-v1-0-802c0ec507cc@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
With commit 5d0efaf47ee90 ("regulator: pca9450: Correct interrupt type"),
there might be interrupt storm for this board. Need to set PAD PUE and PU
together to make pull up work properly.
Fixes: dfcd1b6f7620e ("arm64: dts: freescale: add initial device tree for TQMa8MQML with i.MX8MM")
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
index 29b298af0d739100d33ff43a8b955a37821b3ef7..1b5ba3c47164f28756bb99210a5961bfaa881220 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
@@ -292,7 +292,7 @@ pinctrl_i2c1_gpio: i2c1gpiogrp {
};
pinctrl_pmic: pmicgrp {
- fsl,pins = <MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x94>;
+ fsl,pins = <MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x1d4>;
};
pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
--
2.37.1
^ permalink raw reply related
* Re: [PATCH v2 0/3] media: camss: Link CAMSS power domain on MSM8996
From: Christopher Obbard @ 2026-03-29 13:00 UTC (permalink / raw)
To: Yassine Oudjana, Robert Foss, Todor Tomov, Bryan O'Donoghue,
Andy Gross, Bjorn Andersson, Konrad Dybcio, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Hans Verkuil
Cc: Yassine Oudjana, Vladimir Zapolskiy, linux-media, linux-arm-msm,
devicetree, linux-kernel
In-Reply-To: <20230526180712.8481-1-y.oudjana@protonmail.com>
Hi Yassine,
On Fri, 2023-05-26 at 21:07 +0300, Yassine Oudjana wrote:
> From: Yassine Oudjana <y.oudjana@protonmail.com>
>
> CAMSS on MSM8996 has been broken since commit
> 46cc03175498 ("media: camss: Split power domain management").
> This would happen when trying to start streaming:
>
> [ 199.097810] ------------[ cut here ]------------
> [ 199.097893] camss_top_ahb_clk status stuck at 'off'
> [ 199.097913] WARNING: CPU: 3 PID: 728 at drivers/clk/qcom/clk-branch.c:91 clk_branch_wait+0x140/0x160
> ...
> [ 199.100064] clk_branch_wait+0x140/0x160
> [ 199.100112] clk_branch2_enable+0x30/0x40
> [ 199.100159] clk_core_enable+0x6c/0xb0
> [ 199.100211] clk_enable+0x2c/0x50
> [ 199.100257] camss_enable_clocks+0x94/0xe0 [qcom_camss]
> [ 199.100342] csiphy_set_power+0x154/0x2a0 [qcom_camss]
> ...
> [ 199.101594] ---[ end trace 0000000000000000 ]---
> [ 199.101736] qcom-camss a34000.camss: clock enable failed: -16
> [ 199.101813] qcom-camss a34000.camss: Failed to power up pipeline: -16
>
> Turns out camss_top_ahb_clk needs the CAMSS power domain to be on. Before
> the change, VFE power domains were enabled before CSIPHY enabled clocks,
> and since the CAMSS power domain was their parent, it got enabled as well.
> With the VFE power domains now enabled after CSIPHY is powered on, the
> CAMSS power domain remains off and things go south when CSIPHY tries to
> enable camss_top_ahb_clk.
>
> Link the CAMSS power domain in camss_configure_pd to make sure it gets
> enabled before CSIPHY tries to enable clocks.
Do you have any plans to spin another version of this patch series ?
Cheers!
Chris
^ permalink raw reply
* Re: [PATCH] arm64: dts: allwinner: enable h616 timer support
From: Jernej Škrabec @ 2026-03-29 13:03 UTC (permalink / raw)
To: Michal Piekos
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
Samuel Holland, devicetree, linux-arm-kernel, linux-sunxi,
linux-kernel
In-Reply-To: <n2bupd37br2mp7ls6c5z5ueoancr53tn4mywg2vvrlpyhmkex4@lxe6tfdhwz5e>
Dne nedelja, 29. marec 2026 ob 14:07:19 Srednjeevropski poletni čas je Michal Piekos napisal(a):
> On Sun, Mar 29, 2026 at 01:53:45PM +0200, Jernej Škrabec wrote:
> > Dne nedelja, 29. marec 2026 ob 13:43:04 Srednjeevropski poletni čas je Michal Piekos napisal(a):
> > > Add support for timer by reusing existing sun4i timer driver.
> > >
> > > H616 timer is compatible with earlier sunxi timer variants and provides
> > > both clocksource and clockevent functionality. It runs from 24 MHz
> > > oscillator. It can serve as broadcast clockevent for wake up from idle
> > > states.
> > >
> > > Tested on Orange Pi Zero 3:
> > > - timer is registered as clocksource:
> > > - switching clocksource at runtime works
> > > - timer operates as a broadcast clockevent device
> > > - no regression observed compared to arch_sys_counter
> > >
> > > Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
> > > ---
> > > Test results:
> > >
> > > Clocksource switching:
> > > cat /sys/devices/system/clocksource/clocksource0/available_clocksource
> > > arch_sys_counter timer
> > > echo timer > /sys/devices/system/clocksource/clocksource0/current_clocksource
> > > [ 5031.105997] clocksource: Switched to clocksource timer
> > >
> > > Clockevent configuration:
> > > cat /proc/timer_list
> > > ...
> > > Tick Device: mode: 1
> > > Broadcast device
> > > Clock Event Device: sun4i_tick
> > > max_delta_ns: 178956969070
> > > min_delta_ns: 1000
> > > mult: 51539608
> > > shift: 31
> > > mode: 1
> > > next_event: 9223372036854775807 nsecs
> > > set_next_event: sun4i_clkevt_next_event
> > > shutdown: sun4i_clkevt_shutdown
> > > periodic: sun4i_clkevt_set_periodic
> > > oneshot: sun4i_clkevt_set_oneshot
> > > resume: sun4i_clkevt_shutdown
> > > event_handler: tick_handle_oneshot_broadcast
> > > ...
> > >
> > > Cyclictest measurements:
> > > Dominated by system scheduler latency and do not reflect clocksource
> > > precision.
> > > ---
> > > arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 9 +++++++++
> > > 1 file changed, 9 insertions(+)
> > >
> > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> > > index 8d1110c14bad..bf054869e78b 100644
> > > --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> > > @@ -228,6 +228,15 @@ cpu_speed_grade: cpu-speed-grade@0 {
> > > };
> > > };
> > >
> > > + timer0: timer@3009000 {
> > > + compatible = "allwinner,sun50i-h616-timer",
> > > + "allwinner,sun8i-a23-timer";
> >
> > You have to add above combo to DT bindings.
> >
> > Best regards,
> > Jernej
>
> Not sure I understand your comment correctly but binding for h616 is already
> there:
>
> Documentation/devicetree/bindings/timer/allwinner,sun4i-a10-timer.yaml:21-27
> - items:
> - enum:
> - allwinner,sun20i-d1-timer
> - allwinner,sun50i-a64-timer
> - allwinner,sun50i-h6-timer
> - allwinner,sun50i-h616-timer
> - const: allwinner,sun8i-a23-timer
>
> BR
> Michal
Sorry, sometimes tooling fails me. All good.
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Best regards,
Jernej
>
> >
> > > + reg = <0x03009000 0xa0>;
> > > + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
> > > + <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
> > > + clocks = <&osc24M>;
> > > + };
> > > +
> > > watchdog: watchdog@30090a0 {
> > > compatible = "allwinner,sun50i-h616-wdt",
> > > "allwinner,sun6i-a31-wdt";
> > >
> > > ---
> > > base-commit: be762d8b6dd7efacb61937d20f8475db8f207655
> > > change-id: 20260328-h616-timer-046e6ac3549e
> > >
> > > Best regards,
> > >
> >
> >
> >
> >
>
^ permalink raw reply
* [PATCH net-next 00/10] net: airoha: Support multiple net_devices connected to the same GDM port
From: Lorenzo Bianconi @ 2026-03-29 13:07 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, linux-arm-kernel, linux-mediatek, netdev,
devicetree, Xuegang Lu
EN7581 or AN7583 SoCs support connecting multiple external SerDes (e.g.
Ethernet or USB SerDes) to GDM3 or GDM4 ports via a hw multiplexer that
manages the traffic in a TDM manner. As a result multiple net_devices can
connect to the same GDM{3,4} port and there is a theoretical "1:n"
relation between GDM ports and net_devices.
┌─────────────────────────────────┐
│ │ ┌──────┐
│ P1 GDM1 ├────►MT7530│
│ │ └──────┘
│ │ ETH0 (DSA conduit)
│ │
│ PSE/FE │
│ │
│ │
│ │ ┌─────┐
│ P0 CDM1 ├────►QDMA0│
│ P4 P9 GDM4 │ └─────┘
└──┬─────────────────────────┬────┘
│ │
┌──▼──┐ ┌────▼────┐
│ PPE │ │ MUX │
└─────┘ └─┬─────┬─┘
│ │
┌──▼──┐┌─▼───┐
│ ETH ││ USB │
└─────┘└─────┘
ETH1 ETH2
This series introduces support for multiple net_devices connected to the
same Frame Engine (FE) GDM port (GDM3 or GDM4) via an external hw
multiplexer. Please note GDM1 or GDM2 does not support the connection with
the external multiplexer.
---
Lorenzo Bianconi (10):
dt-bindings: net: airoha: Add EN7581 ethernet-ports properties
net: airoha: Rely on net_device pointer in airoha_dev_setup_tc_block signature
net: airoha: Rely on net_device pointer in HTB callbacks
net: airoha: Rely on net_device pointer in ETS callbacks
net: airoha: Introduce airoha_gdm_dev struct
net: airoha: Move airoha_qdma pointer in airoha_gdm_dev struct
net: airoha: Rely on airoha_gdm_dev pointer in airhoa_is_lan_gdm_port()
net: airoha: Support multiple net_devices for a single FE GDM port
net: airoha: Do not stop GDM port if it is shared
net: airoha: Rename get_src_port_id callback in get_sport
.../devicetree/bindings/net/airoha,en7581-eth.yaml | 44 +-
drivers/net/ethernet/airoha/airoha_eth.c | 626 +++++++++++++--------
drivers/net/ethernet/airoha/airoha_eth.h | 30 +-
drivers/net/ethernet/airoha/airoha_ppe.c | 42 +-
4 files changed, 497 insertions(+), 245 deletions(-)
---
base-commit: 68bb4adb58e114336826e2ecc15ecf62e2890d3e
change-id: 20260324-airoha-eth-multi-serdes-fb4b556ee756
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply
* [PATCH net-next 01/10] dt-bindings: net: airoha: Add EN7581 ethernet-ports properties
From: Lorenzo Bianconi @ 2026-03-29 13:07 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, linux-arm-kernel, linux-mediatek, netdev,
devicetree
In-Reply-To: <20260329-airoha-eth-multi-serdes-v1-0-00f52dc360ca@kernel.org>
EN7581 and AN7583 SoCs support connecting multiple external SerDes to GDM3
or GDM4 ports via a hw multiplexer that manages the traffic in a TDM
manner. As a result multiple net_devices can connect to the same GDM{3,4}
port and there is a theoretical "1:n" relation between GDM ports and
net_devices.
Introduce the ethernet-port property in order to model a given net_device
that is connected via the external multiplexer to the GDM{3,4} port (that
is represented by the ethernet property. Please note GDM1 or GDM2 does not
support the connection with the external multiplexer and are represented
by ethernet property.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
.../devicetree/bindings/net/airoha,en7581-eth.yaml | 44 +++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml b/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
index fbe2ddcdd909cb3d853a4ab9e9fec4af1d096c52..ebbd433e9c9fbfaefd8d07c3678cabc91574d125 100644
--- a/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
+++ b/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
@@ -130,6 +130,30 @@ patternProperties:
maximum: 4
description: GMAC port identifier
+ '#address-cells':
+ const: 1
+ '#size-cells':
+ const: 0
+
+ patternProperties:
+ "^ethernet-port@[0-5]$":
+ type: object
+ unevaluatedProperties: false
+ $ref: ethernet-controller.yaml#
+ description: External ethernet port ID available on the GDM port
+
+ properties:
+ compatible:
+ const: airoha,eth-port
+
+ reg:
+ maxItems: 1
+ description: External ethernet port identifier
+
+ required:
+ - compatible
+ - reg
+
required:
- reg
- compatible
@@ -191,9 +215,27 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
- mac: ethernet@1 {
+ mac1: ethernet@1 {
compatible = "airoha,eth-mac";
reg = <1>;
};
+
+ mac4: ethernet@4 {
+ compatible = "airoha,eth-mac";
+ reg = <4>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet-port@0 {
+ compatible = "airoha,eth-port";
+ reg = <0>;
+ };
+
+ ethernet-port@1 {
+ compatible = "airoha,eth-port";
+ reg = <1>;
+ };
+ };
};
};
--
2.53.0
^ permalink raw reply related
* [PATCH net-next 02/10] net: airoha: Rely on net_device pointer in airoha_dev_setup_tc_block signature
From: Lorenzo Bianconi @ 2026-03-29 13:07 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, linux-arm-kernel, linux-mediatek, netdev,
devicetree, Xuegang Lu
In-Reply-To: <20260329-airoha-eth-multi-serdes-v1-0-00f52dc360ca@kernel.org>
Remove airoha_gdm_port dependency in airoha_dev_setup_tc_block routine
signature and rely on net_device pointer instead. Please note this patch
does not introduce any logical change and it is a preliminary patch to
support multiple net_devices connected to the GDM3 or GDM4 ports via an
external hw multiplexer.
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 743ef0db30980ce74059dfb63553030ef3bf735f..421a154ee7189eb7919382b6cd893ae5d4e03766 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2671,7 +2671,7 @@ static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type,
}
}
-static int airoha_dev_setup_tc_block(struct airoha_gdm_port *port,
+static int airoha_dev_setup_tc_block(struct net_device *dev,
struct flow_block_offload *f)
{
flow_setup_cb_t *cb = airoha_dev_setup_tc_block_cb;
@@ -2684,12 +2684,12 @@ static int airoha_dev_setup_tc_block(struct airoha_gdm_port *port,
f->driver_block_list = &block_cb_list;
switch (f->command) {
case FLOW_BLOCK_BIND:
- block_cb = flow_block_cb_lookup(f->block, cb, port->dev);
+ block_cb = flow_block_cb_lookup(f->block, cb, dev);
if (block_cb) {
flow_block_cb_incref(block_cb);
return 0;
}
- block_cb = flow_block_cb_alloc(cb, port->dev, port->dev, NULL);
+ block_cb = flow_block_cb_alloc(cb, dev, dev, NULL);
if (IS_ERR(block_cb))
return PTR_ERR(block_cb);
@@ -2698,7 +2698,7 @@ static int airoha_dev_setup_tc_block(struct airoha_gdm_port *port,
list_add_tail(&block_cb->driver_list, &block_cb_list);
return 0;
case FLOW_BLOCK_UNBIND:
- block_cb = flow_block_cb_lookup(f->block, cb, port->dev);
+ block_cb = flow_block_cb_lookup(f->block, cb, dev);
if (!block_cb)
return -ENOENT;
@@ -2797,7 +2797,7 @@ static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
return airoha_tc_setup_qdisc_htb(port, type_data);
case TC_SETUP_BLOCK:
case TC_SETUP_FT:
- return airoha_dev_setup_tc_block(port, type_data);
+ return airoha_dev_setup_tc_block(dev, type_data);
default:
return -EOPNOTSUPP;
}
--
2.53.0
^ permalink raw reply related
* [PATCH net-next 03/10] net: airoha: Rely on net_device pointer in HTB callbacks
From: Lorenzo Bianconi @ 2026-03-29 13:07 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, linux-arm-kernel, linux-mediatek, netdev,
devicetree, Xuegang Lu
In-Reply-To: <20260329-airoha-eth-multi-serdes-v1-0-00f52dc360ca@kernel.org>
Remove airoha_gdm_port dependency in HTB tc callback signatures and rely
on net_device pointer instead. Please note this patch does not introduce
any logical change and it is a preliminary patch in order to support
multiple net_devices connected to the same GDM3 or GDM4 port via an
external hw multiplexer.
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 51 ++++++++++++++++++--------------
1 file changed, 28 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 421a154ee7189eb7919382b6cd893ae5d4e03766..e8d4fdbc990195e4b0121ae591066e4fc11ab647 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2476,10 +2476,11 @@ static int airoha_qdma_set_trtcm_token_bucket(struct airoha_qdma *qdma,
mode, val);
}
-static int airoha_qdma_set_tx_rate_limit(struct airoha_gdm_port *port,
+static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,
int channel, u32 rate,
u32 bucket_size)
{
+ struct airoha_gdm_port *port = netdev_priv(netdev);
int i, err;
for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
@@ -2499,21 +2500,21 @@ static int airoha_qdma_set_tx_rate_limit(struct airoha_gdm_port *port,
return 0;
}
-static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port,
+static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */
- struct net_device *dev = port->dev;
- int num_tx_queues = dev->real_num_tx_queues;
- int err;
+ int err, num_tx_queues = netdev->real_num_tx_queues;
+ struct airoha_gdm_port *port = netdev_priv(netdev);
if (opt->parent_classid != TC_HTB_CLASSID_ROOT) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid");
return -EINVAL;
}
- err = airoha_qdma_set_tx_rate_limit(port, channel, rate, opt->quantum);
+ err = airoha_qdma_set_tx_rate_limit(netdev, channel, rate,
+ opt->quantum);
if (err) {
NL_SET_ERR_MSG_MOD(opt->extack,
"failed configuring htb offload");
@@ -2523,9 +2524,10 @@ static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port,
if (opt->command == TC_HTB_NODE_MODIFY)
return 0;
- err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1);
+ err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
if (err) {
- airoha_qdma_set_tx_rate_limit(port, channel, 0, opt->quantum);
+ airoha_qdma_set_tx_rate_limit(netdev, channel, 0,
+ opt->quantum);
NL_SET_ERR_MSG_MOD(opt->extack,
"failed setting real_num_tx_queues");
return err;
@@ -2712,44 +2714,47 @@ static int airoha_dev_setup_tc_block(struct net_device *dev,
}
}
-static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue)
+static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
{
- struct net_device *dev = port->dev;
+ struct airoha_gdm_port *port = netdev_priv(netdev);
- netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1);
- airoha_qdma_set_tx_rate_limit(port, queue + 1, 0, 0);
+ netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
+ airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0);
clear_bit(queue, port->qos_sq_bmap);
}
-static int airoha_tc_htb_delete_leaf_queue(struct airoha_gdm_port *port,
+static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
+ struct airoha_gdm_port *port = netdev_priv(netdev);
if (!test_bit(channel, port->qos_sq_bmap)) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
return -EINVAL;
}
- airoha_tc_remove_htb_queue(port, channel);
+ airoha_tc_remove_htb_queue(netdev, channel);
return 0;
}
-static int airoha_tc_htb_destroy(struct airoha_gdm_port *port)
+static int airoha_tc_htb_destroy(struct net_device *netdev)
{
+ struct airoha_gdm_port *port = netdev_priv(netdev);
int q;
for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
- airoha_tc_remove_htb_queue(port, q);
+ airoha_tc_remove_htb_queue(netdev, q);
return 0;
}
-static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port,
+static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
+ struct airoha_gdm_port *port = netdev_priv(netdev);
if (!test_bit(channel, port->qos_sq_bmap)) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
@@ -2761,23 +2766,23 @@ static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port,
return 0;
}
-static int airoha_tc_setup_qdisc_htb(struct airoha_gdm_port *port,
+static int airoha_tc_setup_qdisc_htb(struct net_device *dev,
struct tc_htb_qopt_offload *opt)
{
switch (opt->command) {
case TC_HTB_CREATE:
break;
case TC_HTB_DESTROY:
- return airoha_tc_htb_destroy(port);
+ return airoha_tc_htb_destroy(dev);
case TC_HTB_NODE_MODIFY:
case TC_HTB_LEAF_ALLOC_QUEUE:
- return airoha_tc_htb_alloc_leaf_queue(port, opt);
+ return airoha_tc_htb_alloc_leaf_queue(dev, opt);
case TC_HTB_LEAF_DEL:
case TC_HTB_LEAF_DEL_LAST:
case TC_HTB_LEAF_DEL_LAST_FORCE:
- return airoha_tc_htb_delete_leaf_queue(port, opt);
+ return airoha_tc_htb_delete_leaf_queue(dev, opt);
case TC_HTB_LEAF_QUERY_QUEUE:
- return airoha_tc_get_htb_get_leaf_queue(port, opt);
+ return airoha_tc_get_htb_get_leaf_queue(dev, opt);
default:
return -EOPNOTSUPP;
}
@@ -2794,7 +2799,7 @@ static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
case TC_SETUP_QDISC_ETS:
return airoha_tc_setup_qdisc_ets(port, type_data);
case TC_SETUP_QDISC_HTB:
- return airoha_tc_setup_qdisc_htb(port, type_data);
+ return airoha_tc_setup_qdisc_htb(dev, type_data);
case TC_SETUP_BLOCK:
case TC_SETUP_FT:
return airoha_dev_setup_tc_block(dev, type_data);
--
2.53.0
^ permalink raw reply related
* [PATCH net-next 04/10] net: airoha: Rely on net_device pointer in ETS callbacks
From: Lorenzo Bianconi @ 2026-03-29 13:07 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, linux-arm-kernel, linux-mediatek, netdev,
devicetree, Xuegang Lu
In-Reply-To: <20260329-airoha-eth-multi-serdes-v1-0-00f52dc360ca@kernel.org>
Remove airoha_gdm_port dependency in ETS tc callback signatures and rely
on net_device pointer instead. Please note this patch does not introduce
any logical change and it is a preliminary patch in order to support
multiple net_devices connected to the same GDM3 or GDM4 port via an
external hw multiplexer.
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index e8d4fdbc990195e4b0121ae591066e4fc11ab647..cefe251234989f05c7a2b36161eb63ba861d8b34 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2122,10 +2122,11 @@ airoha_ethtool_get_rmon_stats(struct net_device *dev,
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
-static int airoha_qdma_set_chan_tx_sched(struct airoha_gdm_port *port,
+static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
int channel, enum tx_sched_mode mode,
const u16 *weights, u8 n_weights)
{
+ struct airoha_gdm_port *port = netdev_priv(netdev);
int i;
for (i = 0; i < AIROHA_NUM_TX_RING; i++)
@@ -2157,17 +2158,15 @@ static int airoha_qdma_set_chan_tx_sched(struct airoha_gdm_port *port,
return 0;
}
-static int airoha_qdma_set_tx_prio_sched(struct airoha_gdm_port *port,
- int channel)
+static int airoha_qdma_set_tx_prio_sched(struct net_device *dev, int channel)
{
static const u16 w[AIROHA_NUM_QOS_QUEUES] = {};
- return airoha_qdma_set_chan_tx_sched(port, channel, TC_SCH_SP, w,
+ return airoha_qdma_set_chan_tx_sched(dev, channel, TC_SCH_SP, w,
ARRAY_SIZE(w));
}
-static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port,
- int channel,
+static int airoha_qdma_set_tx_ets_sched(struct net_device *dev, int channel,
struct tc_ets_qopt_offload *opt)
{
struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params;
@@ -2208,14 +2207,15 @@ static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port,
else if (nstrict < AIROHA_NUM_QOS_QUEUES - 1)
mode = nstrict + 1;
- return airoha_qdma_set_chan_tx_sched(port, channel, mode, w,
+ return airoha_qdma_set_chan_tx_sched(dev, channel, mode, w,
ARRAY_SIZE(w));
}
-static int airoha_qdma_get_tx_ets_stats(struct airoha_gdm_port *port,
- int channel,
+static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,
struct tc_ets_qopt_offload *opt)
{
+ struct airoha_gdm_port *port = netdev_priv(netdev);
+
u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
REG_CNTR_VAL(channel << 1));
u64 fwd_tx_packets = airoha_qdma_rr(port->qdma,
@@ -2230,7 +2230,7 @@ static int airoha_qdma_get_tx_ets_stats(struct airoha_gdm_port *port,
return 0;
}
-static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port,
+static int airoha_tc_setup_qdisc_ets(struct net_device *dev,
struct tc_ets_qopt_offload *opt)
{
int channel;
@@ -2243,12 +2243,12 @@ static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port,
switch (opt->command) {
case TC_ETS_REPLACE:
- return airoha_qdma_set_tx_ets_sched(port, channel, opt);
+ return airoha_qdma_set_tx_ets_sched(dev, channel, opt);
case TC_ETS_DESTROY:
/* PRIO is default qdisc scheduler */
- return airoha_qdma_set_tx_prio_sched(port, channel);
+ return airoha_qdma_set_tx_prio_sched(dev, channel);
case TC_ETS_STATS:
- return airoha_qdma_get_tx_ets_stats(port, channel, opt);
+ return airoha_qdma_get_tx_ets_stats(dev, channel, opt);
default:
return -EOPNOTSUPP;
}
@@ -2793,11 +2793,9 @@ static int airoha_tc_setup_qdisc_htb(struct net_device *dev,
static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
-
switch (type) {
case TC_SETUP_QDISC_ETS:
- return airoha_tc_setup_qdisc_ets(port, type_data);
+ return airoha_tc_setup_qdisc_ets(dev, type_data);
case TC_SETUP_QDISC_HTB:
return airoha_tc_setup_qdisc_htb(dev, type_data);
case TC_SETUP_BLOCK:
--
2.53.0
^ permalink raw reply related
* [PATCH net-next 05/10] net: airoha: Introduce airoha_gdm_dev struct
From: Lorenzo Bianconi @ 2026-03-29 13:07 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, linux-arm-kernel, linux-mediatek, netdev,
devicetree, Xuegang Lu
In-Reply-To: <20260329-airoha-eth-multi-serdes-v1-0-00f52dc360ca@kernel.org>
EN7581 and AN7583 SoCs support connecting multiple external SerDes to GDM3
or GDM4 ports via a hw multiplexer that manages the traffic in a TDM
manner. As a result multiple net_devices can connect to the same GDM{3,4}
port and there is a theoretical "1:n" relation between GDM port and
net_devices.
Introduce airoha_gdm_dev struct to collect net_device related info (e.g.
net_device and external phy pointer). Please note this is just a
preliminary patch and we are still supporting a single net_device for
each GDM port. Subsequent patches will add support for multiple net_devices
connected to the same GDM port.
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 268 +++++++++++++++++++------------
drivers/net/ethernet/airoha/airoha_eth.h | 13 +-
drivers/net/ethernet/airoha/airoha_ppe.c | 17 +-
3 files changed, 180 insertions(+), 118 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index cefe251234989f05c7a2b36161eb63ba861d8b34..2ad86cad89ce3cbdf2a1f881dad124af8a96961a 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -616,6 +616,7 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
struct page *page = virt_to_head_page(e->buf);
u32 desc_ctrl = le32_to_cpu(desc->ctrl);
struct airoha_gdm_port *port;
+ struct net_device *netdev;
int data_len, len, p;
if (!(desc_ctrl & QDMA_DESC_DONE_MASK))
@@ -638,6 +639,7 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
goto free_frag;
port = eth->ports[p];
+ netdev = port->dev->dev;
if (!q->skb) { /* first buffer */
q->skb = napi_build_skb(e->buf, q->buf_size);
if (!q->skb)
@@ -645,8 +647,8 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
__skb_put(q->skb, len);
skb_mark_for_recycle(q->skb);
- q->skb->dev = port->dev;
- q->skb->protocol = eth_type_trans(q->skb, port->dev);
+ q->skb->dev = netdev;
+ q->skb->protocol = eth_type_trans(q->skb, netdev);
q->skb->ip_summed = CHECKSUM_UNNECESSARY;
skb_record_rx_queue(q->skb, qid);
} else { /* scattered frame */
@@ -664,7 +666,7 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
if (FIELD_GET(QDMA_DESC_MORE_MASK, desc_ctrl))
continue;
- if (netdev_uses_dsa(port->dev)) {
+ if (netdev_uses_dsa(netdev)) {
/* PPE module requires untagged packets to work
* properly and it provides DSA port index via the
* DMA descriptor. Report DSA tag to the DSA stack
@@ -1622,19 +1624,20 @@ static void airoha_update_hw_stats(struct airoha_gdm_port *port)
spin_unlock(&port->stats.lock);
}
-static int airoha_dev_open(struct net_device *dev)
+static int airoha_dev_open(struct net_device *netdev)
{
- int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN;
- struct airoha_gdm_port *port = netdev_priv(dev);
+ int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_qdma *qdma = port->qdma;
u32 pse_port = FE_PSE_PORT_PPE1;
- netif_tx_start_all_queues(dev);
+ netif_tx_start_all_queues(netdev);
err = airoha_set_vip_for_gdm_port(port, true);
if (err)
return err;
- if (netdev_uses_dsa(dev))
+ if (netdev_uses_dsa(netdev))
airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
GDM_STAG_EN_MASK);
else
@@ -1662,19 +1665,20 @@ static int airoha_dev_open(struct net_device *dev)
return 0;
}
-static int airoha_dev_stop(struct net_device *dev)
+static int airoha_dev_stop(struct net_device *netdev)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_qdma *qdma = port->qdma;
int i, err;
- netif_tx_disable(dev);
+ netif_tx_disable(netdev);
err = airoha_set_vip_for_gdm_port(port, false);
if (err)
return err;
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++)
- netdev_tx_reset_subqueue(dev, i);
+ netdev_tx_reset_subqueue(netdev, i);
airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
FE_PSE_PORT_DROP);
@@ -1695,16 +1699,17 @@ static int airoha_dev_stop(struct net_device *dev)
return 0;
}
-static int airoha_dev_set_macaddr(struct net_device *dev, void *p)
+static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
int err;
- err = eth_mac_addr(dev, p);
+ err = eth_mac_addr(netdev, p);
if (err)
return err;
- airoha_set_macaddr(port, dev->dev_addr);
+ airoha_set_macaddr(port, netdev->dev_addr);
return 0;
}
@@ -1767,16 +1772,17 @@ static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
return 0;
}
-static int airoha_dev_init(struct net_device *dev)
+static int airoha_dev_init(struct net_device *netdev)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
- struct airoha_eth *eth = port->eth;
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
int i;
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)];
- port->dev->irq = port->qdma->irq_banks[0].irq;
- airoha_set_macaddr(port, dev->dev_addr);
+ dev->dev->irq = port->qdma->irq_banks[0].irq;
+ airoha_set_macaddr(port, netdev->dev_addr);
switch (port->id) {
case AIROHA_GDM3_IDX:
@@ -1800,10 +1806,11 @@ static int airoha_dev_init(struct net_device *dev)
return 0;
}
-static void airoha_dev_get_stats64(struct net_device *dev,
+static void airoha_dev_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *storage)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
unsigned int start;
airoha_update_hw_stats(port);
@@ -1822,36 +1829,39 @@ static void airoha_dev_get_stats64(struct net_device *dev,
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
-static int airoha_dev_change_mtu(struct net_device *dev, int mtu)
+static int airoha_dev_change_mtu(struct net_device *netdev, int mtu)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_eth *eth = port->qdma->eth;
u32 len = ETH_HLEN + mtu + ETH_FCS_LEN;
airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
GDM_LONG_LEN_MASK,
FIELD_PREP(GDM_LONG_LEN_MASK, len));
- WRITE_ONCE(dev->mtu, mtu);
+ WRITE_ONCE(netdev->mtu, mtu);
return 0;
}
-static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb,
+static u16 airoha_dev_select_queue(struct net_device *netdev,
+ struct sk_buff *skb,
struct net_device *sb_dev)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
int queue, channel;
/* For dsa device select QoS channel according to the dsa user port
* index, rely on port id otherwise. Select QoS queue based on the
* skb priority.
*/
- channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id;
+ channel = netdev_uses_dsa(netdev) ? skb_get_queue_mapping(skb) : port->id;
channel = channel % AIROHA_NUM_QOS_CHANNELS;
queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */
queue = channel * AIROHA_NUM_QOS_QUEUES + queue;
- return queue < dev->num_tx_queues ? queue : 0;
+ return queue < netdev->num_tx_queues ? queue : 0;
}
static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev)
@@ -1915,9 +1925,10 @@ int airoha_get_fe_port(struct airoha_gdm_port *port)
}
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
- struct net_device *dev)
+ struct net_device *netdev)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_qdma *qdma = port->qdma;
u32 nr_frags, tag, msg0, msg1, len;
struct airoha_queue_entry *e;
@@ -1930,7 +1941,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
u8 fport;
qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx);
- tag = airoha_get_dsa_tag(skb, dev);
+ tag = airoha_get_dsa_tag(skb, netdev);
msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK,
qid / AIROHA_NUM_QOS_QUEUES) |
@@ -1966,7 +1977,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
spin_lock_bh(&q->lock);
- txq = netdev_get_tx_queue(dev, qid);
+ txq = netdev_get_tx_queue(netdev, qid);
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
if (q->queued + nr_frags >= q->ndesc) {
@@ -1989,9 +2000,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
dma_addr_t addr;
u32 val;
- addr = dma_map_single(dev->dev.parent, data, len,
+ addr = dma_map_single(netdev->dev.parent, data, len,
DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(dev->dev.parent, addr)))
+ if (unlikely(dma_mapping_error(netdev->dev.parent, addr)))
goto error_unmap;
list_move_tail(&e->list, &tx_list);
@@ -2038,8 +2049,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
while (!list_empty(&tx_list)) {
e = list_first_entry(&tx_list, struct airoha_queue_entry,
list);
- dma_unmap_single(dev->dev.parent, e->dma_addr, e->dma_len,
- DMA_TO_DEVICE);
+ dma_unmap_single(netdev->dev.parent, e->dma_addr,
+ e->dma_len, DMA_TO_DEVICE);
e->dma_addr = 0;
list_move_tail(&e->list, &q->tx_list);
}
@@ -2047,25 +2058,27 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
spin_unlock_bh(&q->lock);
error:
dev_kfree_skb_any(skb);
- dev->stats.tx_dropped++;
+ netdev->stats.tx_dropped++;
return NETDEV_TX_OK;
}
-static void airoha_ethtool_get_drvinfo(struct net_device *dev,
+static void airoha_ethtool_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *info)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_eth *eth = port->qdma->eth;
strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
}
-static void airoha_ethtool_get_mac_stats(struct net_device *dev,
+static void airoha_ethtool_get_mac_stats(struct net_device *netdev,
struct ethtool_eth_mac_stats *stats)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
unsigned int start;
airoha_update_hw_stats(port);
@@ -2093,11 +2106,12 @@ static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = {
};
static void
-airoha_ethtool_get_rmon_stats(struct net_device *dev,
+airoha_ethtool_get_rmon_stats(struct net_device *netdev,
struct ethtool_rmon_stats *stats,
const struct ethtool_rmon_hist_range **ranges)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_hw_stats *hw_stats = &port->stats;
unsigned int start;
@@ -2126,7 +2140,8 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
int channel, enum tx_sched_mode mode,
const u16 *weights, u8 n_weights)
{
- struct airoha_gdm_port *port = netdev_priv(netdev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
int i;
for (i = 0; i < AIROHA_NUM_TX_RING; i++)
@@ -2214,7 +2229,8 @@ static int airoha_qdma_set_tx_ets_sched(struct net_device *dev, int channel,
static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,
struct tc_ets_qopt_offload *opt)
{
- struct airoha_gdm_port *port = netdev_priv(netdev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
REG_CNTR_VAL(channel << 1));
@@ -2480,7 +2496,8 @@ static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,
int channel, u32 rate,
u32 bucket_size)
{
- struct airoha_gdm_port *port = netdev_priv(netdev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
int i, err;
for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
@@ -2506,7 +2523,8 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */
int err, num_tx_queues = netdev->real_num_tx_queues;
- struct airoha_gdm_port *port = netdev_priv(netdev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
if (opt->parent_classid != TC_HTB_CLASSID_ROOT) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid");
@@ -2617,11 +2635,12 @@ static int airoha_tc_matchall_act_validate(struct tc_cls_matchall_offload *f)
return 0;
}
-static int airoha_dev_tc_matchall(struct net_device *dev,
+static int airoha_dev_tc_matchall(struct net_device *netdev,
struct tc_cls_matchall_offload *f)
{
enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT;
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
u32 rate = 0, bucket_size = 0;
switch (f->command) {
@@ -2656,18 +2675,19 @@ static int airoha_dev_tc_matchall(struct net_device *dev,
static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type,
void *type_data, void *cb_priv)
{
- struct net_device *dev = cb_priv;
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct net_device *netdev = cb_priv;
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_eth *eth = port->qdma->eth;
- if (!tc_can_offload(dev))
+ if (!tc_can_offload(netdev))
return -EOPNOTSUPP;
switch (type) {
case TC_SETUP_CLSFLOWER:
return airoha_ppe_setup_tc_block_cb(ð->ppe->dev, type_data);
case TC_SETUP_CLSMATCHALL:
- return airoha_dev_tc_matchall(dev, type_data);
+ return airoha_dev_tc_matchall(netdev, type_data);
default:
return -EOPNOTSUPP;
}
@@ -2716,7 +2736,8 @@ static int airoha_dev_setup_tc_block(struct net_device *dev,
static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
{
- struct airoha_gdm_port *port = netdev_priv(netdev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0);
@@ -2727,7 +2748,8 @@ static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
- struct airoha_gdm_port *port = netdev_priv(netdev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
if (!test_bit(channel, port->qos_sq_bmap)) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
@@ -2741,7 +2763,8 @@ static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
static int airoha_tc_htb_destroy(struct net_device *netdev)
{
- struct airoha_gdm_port *port = netdev_priv(netdev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
int q;
for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
@@ -2754,7 +2777,8 @@ static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
- struct airoha_gdm_port *port = netdev_priv(netdev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
if (!test_bit(channel, port->qos_sq_bmap)) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
@@ -2790,8 +2814,8 @@ static int airoha_tc_setup_qdisc_htb(struct net_device *dev,
return 0;
}
-static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
- void *type_data)
+static int airoha_dev_tc_setup(struct net_device *dev,
+ enum tc_setup_type type, void *type_data)
{
switch (type) {
case TC_SETUP_QDISC_ETS:
@@ -2857,25 +2881,81 @@ static void airoha_metadata_dst_free(struct airoha_gdm_port *port)
}
}
-bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
- struct airoha_gdm_port *port)
+bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
+ struct airoha_gdm_dev *dev)
{
int i;
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
- if (eth->ports[i] == port)
+ struct airoha_gdm_port *port = eth->ports[i];
+
+ if (!port)
+ continue;
+
+ if (port->dev == dev)
return true;
}
return false;
}
+static int airoha_alloc_gdm_device(struct airoha_eth *eth,
+ struct airoha_gdm_port *port,
+ struct device_node *np)
+{
+ struct airoha_gdm_dev *dev;
+ struct net_device *netdev;
+ int err;
+
+ netdev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*dev),
+ AIROHA_NUM_NETDEV_TX_RINGS,
+ AIROHA_NUM_RX_RING);
+ if (!netdev) {
+ dev_err(eth->dev, "alloc_etherdev failed\n");
+ return -ENOMEM;
+ }
+
+ netdev->netdev_ops = &airoha_netdev_ops;
+ netdev->ethtool_ops = &airoha_ethtool_ops;
+ netdev->max_mtu = AIROHA_MAX_MTU;
+ netdev->watchdog_timeo = 5 * HZ;
+ netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO6 |
+ NETIF_F_IPV6_CSUM | NETIF_F_SG | NETIF_F_TSO |
+ NETIF_F_HW_TC;
+ netdev->features |= netdev->hw_features;
+ netdev->vlan_features = netdev->hw_features;
+ netdev->dev.of_node = np;
+ SET_NETDEV_DEV(netdev, eth->dev);
+
+ /* reserve hw queues for HTB offloading */
+ err = netif_set_real_num_tx_queues(netdev, AIROHA_NUM_TX_RING);
+ if (err)
+ return err;
+
+ err = of_get_ethdev_address(np, netdev);
+ if (err) {
+ if (err == -EPROBE_DEFER)
+ return err;
+
+ eth_hw_addr_random(netdev);
+ dev_info(eth->dev, "generated random MAC address %pM\n",
+ netdev->dev_addr);
+ }
+
+ dev = netdev_priv(netdev);
+ dev->dev = netdev;
+ dev->port = port;
+ port->dev = dev;
+ dev->eth = eth;
+
+ return 0;
+}
+
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
struct device_node *np)
{
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
struct airoha_gdm_port *port;
- struct net_device *dev;
int err, p;
u32 id;
@@ -2897,51 +2977,20 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
return -EINVAL;
}
- dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port),
- AIROHA_NUM_NETDEV_TX_RINGS,
- AIROHA_NUM_RX_RING);
- if (!dev) {
- dev_err(eth->dev, "alloc_etherdev failed\n");
+ port = devm_kzalloc(eth->dev, sizeof(*port), GFP_KERNEL);
+ if (!port)
return -ENOMEM;
- }
-
- dev->netdev_ops = &airoha_netdev_ops;
- dev->ethtool_ops = &airoha_ethtool_ops;
- dev->max_mtu = AIROHA_MAX_MTU;
- dev->watchdog_timeo = 5 * HZ;
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
- NETIF_F_TSO6 | NETIF_F_IPV6_CSUM |
- NETIF_F_SG | NETIF_F_TSO |
- NETIF_F_HW_TC;
- dev->features |= dev->hw_features;
- dev->vlan_features = dev->hw_features;
- dev->dev.of_node = np;
- SET_NETDEV_DEV(dev, eth->dev);
-
- /* reserve hw queues for HTB offloading */
- err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING);
- if (err)
- return err;
-
- err = of_get_ethdev_address(np, dev);
- if (err) {
- if (err == -EPROBE_DEFER)
- return err;
-
- eth_hw_addr_random(dev);
- dev_info(eth->dev, "generated random MAC address %pM\n",
- dev->dev_addr);
- }
- port = netdev_priv(dev);
u64_stats_init(&port->stats.syncp);
spin_lock_init(&port->stats.lock);
- port->eth = eth;
- port->dev = dev;
port->id = id;
eth->ports[p] = port;
- return airoha_metadata_dst_alloc(port);
+ err = airoha_metadata_dst_alloc(port);
+ if (err)
+ return err;
+
+ return airoha_alloc_gdm_device(eth, port, np);
}
static int airoha_register_gdm_devices(struct airoha_eth *eth)
@@ -2955,7 +3004,7 @@ static int airoha_register_gdm_devices(struct airoha_eth *eth)
if (!port)
continue;
- err = register_netdev(port->dev);
+ err = register_netdev(port->dev->dev);
if (err)
return err;
}
@@ -3064,12 +3113,14 @@ static int airoha_probe(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
+ struct airoha_gdm_dev *dev;
if (!port)
continue;
- if (port->dev->reg_state == NETREG_REGISTERED)
- unregister_netdev(port->dev);
+ dev = port->dev;
+ if (dev && dev->dev->reg_state == NETREG_REGISTERED)
+ unregister_netdev(dev->dev);
airoha_metadata_dst_free(port);
}
airoha_hw_cleanup(eth);
@@ -3090,11 +3141,14 @@ static void airoha_remove(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
+ struct airoha_gdm_dev *dev;
if (!port)
continue;
- unregister_netdev(port->dev);
+ dev = port->dev;
+ if (dev)
+ unregister_netdev(dev->dev);
airoha_metadata_dst_free(port);
}
airoha_hw_cleanup(eth);
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index af29fc74165b8fffb59f45b4725dbd963f1b876d..b2598b4ee53e1f5c7a3274f0b9ac2d5bf12318fc 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -532,10 +532,15 @@ struct airoha_qdma {
struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
};
+struct airoha_gdm_dev {
+ struct airoha_gdm_port *port;
+ struct net_device *dev;
+ struct airoha_eth *eth;
+};
+
struct airoha_gdm_port {
struct airoha_qdma *qdma;
- struct airoha_eth *eth;
- struct net_device *dev;
+ struct airoha_gdm_dev *dev;
int id;
struct airoha_hw_stats stats;
@@ -648,8 +653,8 @@ static inline bool airoha_is_7583(struct airoha_eth *eth)
}
int airoha_get_fe_port(struct airoha_gdm_port *port);
-bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
- struct airoha_gdm_port *port);
+bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
+ struct airoha_gdm_dev *dev);
void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id);
bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index c057bb2d105d92947bb8c421d89ee94fc0c10f2f..69b449837d201bfd8f182ae18d788ca69c5daf47 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -291,12 +291,12 @@ static void airoha_ppe_foe_set_bridge_addrs(struct airoha_foe_bridge *br,
static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
struct airoha_foe_entry *hwe,
- struct net_device *dev, int type,
+ struct net_device *netdev, int type,
struct airoha_flow_data *data,
int l4proto)
{
u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val;
- int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&dev);
+ int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&netdev);
struct airoha_foe_mac_info_common *l2;
u8 smac_id = 0xf;
@@ -312,10 +312,11 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
hwe->ib1 = val;
val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f);
- if (dev) {
+ if (netdev) {
struct airoha_wdma_info info = {};
- if (!airoha_ppe_get_wdma_info(dev, data->eth.h_dest, &info)) {
+ if (!airoha_ppe_get_wdma_info(netdev, data->eth.h_dest,
+ &info)) {
val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, info.idx) |
FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT,
FE_PSE_PORT_CDM4);
@@ -325,12 +326,14 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
FIELD_PREP(AIROHA_FOE_MAC_WDMA_WCID,
info.wcid);
} else {
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port;
u8 pse_port;
- if (!airoha_is_valid_gdm_port(eth, port))
+ if (!airoha_is_valid_gdm_dev(eth, dev))
return -EINVAL;
+ port = dev->port;
if (dsa_port >= 0 || eth->ports[1])
pse_port = port->id == 4 ? FE_PSE_PORT_GDM4
: port->id;
@@ -1430,7 +1433,7 @@ void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
{
struct airoha_eth *eth = port->qdma->eth;
- struct net_device *dev = port->dev;
+ struct net_device *dev = port->dev->dev;
const u8 *addr = dev->dev_addr;
u32 val;
--
2.53.0
^ permalink raw reply related
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