* Re: [PATCH] KVM: arm64: vgic: Check the interrupt is still ours before migrating it
From: Hyunwoo Kim @ 2026-06-15 5:43 UTC (permalink / raw)
To: Marc Zyngier
Cc: Oliver Upton, joey.gouly, seiden, suzuki.poulose, yuzenghui,
catalin.marinas, will, Sascha.Bischoff, jic23, timothy.hayes,
andre.przywara, linux-arm-kernel, kvmarm, imv4bel
In-Reply-To: <87ldch884j.wl-maz@kernel.org>
On Sun, Jun 14, 2026 at 04:16:44PM +0100, Marc Zyngier wrote:
> On Fri, 12 Jun 2026 03:22:35 +0100,
> Hyunwoo Kim <imv4bel@gmail.com> wrote:
> >
> > On Wed, Jun 10, 2026 at 05:00:25PM +0100, Marc Zyngier wrote:
> > > It's rather unclear to me what the semantics of this are.
> > >
> > > If vcpu-a decides to nuke the LPIs of vcpu-b and the LPI had in the
> > > meantime been migrated to vcpu-c, but obviously not observed by vcpu-c
> > > yet as the LPI is still on vcpu-b's AP-list, then I don't see the
> > > point in keeping this state.
> > >
> > > Am I missing something obvious?
> >
> > I looked a bit more into Oliver's review, the one suggesting that pending
> > be cleared only for resident LPIs while the ones being migrated are left
> > in place.
> >
> > What the leave preserves is the pending edge of a single LPI whose target
> > is already vcpu-c but which is still on vcpu-b's ap_list. This edge is
> > always lost when we just clear it, but for a device that fires again a
> > later INT reaches vcpu-c through the oracle, so it is mostly harmless.
>
> Not completely harmless. When the guest writes EnableLPIs==0, it
> accepts the lost of any pending bit that could be stored. These won't
> be regenerated, unless the device signals a new event that maps to the
> same LPIs. But again, this is the guest's own decision, and I don't
> see a reason to prevent it from shooting itself in the foot.
>
> > The
> > exception is a software LPI that never fires again(irq->hw == false):
> > that edge is then lost with no way to recover it, because
> > its_sync_lpi_pending_table only re-syncs the LPIs whose target_vcpu matches,
> > and the disable path does no pending writeback. I am not entirely sure about
> > this part, though.
>
> I don't think this is a problem, as the architecture doesn't guarantee
> the state of the pending table after turning EnableLPIs off. There's
> even a note recommending to move the interrupts to another RD before
> doing that.
>
> >
> > Since this does not look like the common case, if it does not need to be
> > covered I will send v2 keeping only the pending clear and the ref hold in
> > vgic_prune_ap_list(). What do you think?
>
> So that it is entirely unambiguous, my suggestion is to have this:
>
> diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
> index 5a4768d8cd4f3..70a161383e5a6 100644
> --- a/arch/arm64/kvm/vgic/vgic.c
> +++ b/arch/arm64/kvm/vgic/vgic.c
> @@ -203,6 +203,7 @@ void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu)
> list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list) {
> if (irq_is_lpi(vcpu->kvm, irq->intid)) {
> raw_spin_lock(&irq->irq_lock);
> + irq->pending_latch = false;
> list_del(&irq->ap_list);
> irq->vcpu = NULL;
> raw_spin_unlock(&irq->irq_lock);
> @@ -792,7 +793,11 @@ static void vgic_prune_ap_list(struct kvm_vcpu *vcpu)
> continue;
> }
>
> - /* This interrupt looks like it has to be migrated. */
> + /*
> + * This interrupt looks like it has to be migrated,
> + * make sure it is kept alive while locks are dropped.
> + */
> + vgic_get_irq_ref(irq);
>
> raw_spin_unlock(&irq->irq_lock);
> raw_spin_unlock(&vgic_cpu->ap_list_lock);
> @@ -836,6 +841,8 @@ static void vgic_prune_ap_list(struct kvm_vcpu *vcpu)
> raw_spin_unlock(&vcpuB->arch.vgic_cpu.ap_list_lock);
> raw_spin_unlock(&vcpuA->arch.vgic_cpu.ap_list_lock);
>
> + deleted_lpis |= vgic_put_irq_norelease(vcpu->kvm, irq);
> +
> if (target_vcpu_needs_kick) {
> kvm_make_request(KVM_REQ_IRQ_PENDING, target_vcpu);
> kvm_vcpu_kick(target_vcpu);
>
> Could you please give it a go with whatever reproducer you have?
I confirmed your diff fixes the issue. Could you submit this
patch? Feel free to add Tested-by: Hyunwoo Kim <imv4bel@gmail.com>
Best regards,
Hyunwoo Kim
^ permalink raw reply
* Re: [PATCH RFC 1/2] dt-bindings: pinctl: amlogic,pinctrl-a4: Add gpio irq property
From: Krzysztof Kozlowski @ 2026-06-15 5:32 UTC (permalink / raw)
To: Xianwei Zhao, Conor Dooley
Cc: Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
linux-amlogic, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <a79e58b5-3a11-4593-847d-ba92527549bf@amlogic.com>
On 15/06/2026 04:47, Xianwei Zhao wrote:
> Hi Conor,
> Thanks for your review.
>
> On 2026/6/12 01:39, Conor Dooley wrote:
>> Subject:
>> Re: [PATCH RFC 1/2] dt-bindings: pinctl: amlogic,pinctrl-a4: Add gpio
>> irq property
>> From:
>> Conor Dooley <conor@kernel.org>
>> Date:
>> 2026/6/12 01:39
>>
>> To:
>> xianwei.zhao@amlogic.com
>> CC:
>> Linus Walleij <linusw@kernel.org>, Rob Herring <robh@kernel.org>,
>> Krzysztof Kozlowski <krzk+dt@kernel.org>, Conor Dooley
>> <conor+dt@kernel.org>, Neil Armstrong <neil.armstrong@linaro.org>, Kevin
>> Hilman <khilman@baylibre.com>, Jerome Brunet <jbrunet@baylibre.com>,
>> Martin Blumenstingl <martin.blumenstingl@googlemail.com>,
>> linux-amlogic@lists.infradead.org, linux-gpio@vger.kernel.org,
>> devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
>> linux-arm-kernel@lists.infradead.org
>>
>>
>>
>> On Thu, Jun 11, 2026 at 07:54:33AM +0000, Xianwei Zhao via B4 Relay wrote:
>>> From: Xianwei Zhao<xianwei.zhao@amlogic.com>
>>>
>>> Add the hw-irq property for each GPIO bank and enable interrupt-parent
>>> for pinctrl so that gpiod_to_irq() can translate GPIO lines to IRQs.
>> Uhhhhh, what? Why can't you just use the normal interrupts property?
>>
>
> The interrupt cannot be used directly because the GPIO bank only
> provides an IRQ base, which does not have a one-to-one mapping with the
> actual hardware interrupts.
>
> On Amlogic SoCs, GPIO interrupts are handled through a mux. Multiple
> GPIO pins are mapped to a limited number of real interrupt sources. The
> implementation can be found here:
>
> https://github.com/torvalds/linux/blob/master/drivers/irqchip/irq-meson-gpio.c
>
> To use a GPIO interrupt, an unused hardware interrupt must first be
> allocated, and then the corresponding mux register must be configured.
> This allocation and mapping are already implemented in the existing driver.
>
> In that driver, the mapping is performed dynamically rather than simply
> calculating:
>
> irq = irq_start + gpio_offset
>
> If the interrupt is used directly, only the GPIO index can be obtained.
If it is performed dynamically, then it is not suitable for DT.
You still did not explain what hardware aspect exactly is described by
"hw-irq".
> The real interrupt number cannot be derived by simply adding an offset,
> because the hardware interrupt must be allocated first. Pre-allocating
> all interrupts during initialization would prevent later GPIOs from
> obtaining available interrupt sources.
>
> Perhaps other names would be more appropriate here, such as "irq_start".
>
>>> Signed-off-by: Xianwei Zhao<xianwei.zhao@amlogic.com>
>>> ---
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH] arm64: kgdb: Fix interrupt-induced single-step exception
From: liuqiqi @ 2026-06-15 5:29 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon
Cc: Mark Rutland, linux-kernel, Tongbo Wei, Qiqi Liu,
linux-arm-kernel
From: Qiqi Liu <liuqiqi@kylinos.cn>
After entering kdb due to breakpoint, when we execute 'ss' or 'go'
(will delay installing breakpoints, do single-step first),
and it will enter kdb again.
We found that due to context switching caused by interrupt,
the instruction at ss is no longer the original breakpoint instruction.
Before the patch:
[root@localhost ~]# echo g > /proc/sysrq-trigger
Entering kdb (current=0xffff030004f2bc00, pid 8818) on processor 15 due to Keyboard Entry
[15]kdb> bp sysctl_vm_numa_stat_handler
Instruction(i) BP #0 at 0xffffae550650c810 (sysctl_vm_numa_stat_handler)
is enabled addr at 0xffffae550650c810, hardtype=0 installed=0
[15]kdb> g
[root@localhost ~]# echo 1 > /proc/sys/vm/numa_stat
Entering kdb (current=0xffff030004f2bc00, pid 8818) on processor 12 due to Breakpoint @ 0xffffae550650c810
[12]kdb> g
Entering kdb (current=0xffff030004f2bc00, pid 8818) on processor 12 due to Breakpoint @ 0xffffae550650c810
[12]kdb> g
After the patch:
[root@localhost ~]# echo g > /proc/sysrq-trigger
Entering kdb (current=0xfffff010012c36400, pid 6488) on processor 41 due to Keyboard Entry
[41]kdb> bp sysctl_vm_numa_stat_handler
Instruction(i) BP #0 at 0xfffffd1768c2dc7c8 (sysctl_vm_numa_stat_handler)
is enabled addr at ffffdf1768c2dc7c8, hardtype=0 installed=0
[41]kdb> g
[root@localhost ~]# echo 1 > /proc/sys/vm/numa_stat
Entering kdb (current=0xfffff010012c36400, pid 6488) on processor 7 due to Breakpoint @ 0xfffffd1768c2dc7c8
[7]kdb> g
[root@localhost ~]#
Fixes: 44679a4f142b ("arm64: KGDB: Add step debugging support")
Co-developed-by: Tongbo Wei <kf.weitongbo@h3c.com>
Signed-off-by: Tongbo Wei <kf.weitongbo@h3c.com>
Signed-off-by: Qiqi Liu <liuqiqi@kylinos.cn>
---
arch/arm64/kernel/kgdb.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
index 968324a79a89..e9a246a0c34f 100644
--- a/arch/arm64/kernel/kgdb.c
+++ b/arch/arm64/kernel/kgdb.c
@@ -101,6 +101,8 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
{ "fpcr", 4, -1 },
};
+static DEFINE_PER_CPU(unsigned int, kgdb_pstate);
+
char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
{
if (regno >= DBG_MAX_REG_NUM || regno < 0)
@@ -207,6 +209,8 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
err = 0;
break;
case 's':
+ __this_cpu_write(kgdb_pstate, linux_regs->pstate);
+ linux_regs->pstate |= PSR_I_BIT;
/*
* Update step address value with address passed
* with step packet.
@@ -252,9 +256,17 @@ NOKPROBE_SYMBOL(kgdb_compiled_brk_handler);
int kgdb_single_step_handler(struct pt_regs *regs, unsigned long esr)
{
+ unsigned int pstate;
if (!kgdb_single_step)
return DBG_HOOK_ERROR;
+ /* restore interrupt mask status */
+ pstate = __this_cpu_read(kgdb_pstate);
+ if (pstate & PSR_I_BIT)
+ regs->pstate |= PSR_I_BIT;
+ else
+ regs->pstate &= ~PSR_I_BIT;
+
kgdb_handle_exception(0, SIGTRAP, 0, regs);
return DBG_HOOK_HANDLED;
}
--
2.25.1
^ permalink raw reply related
* [PATCH net-next v3 8/8] net: dsa: mt7530: implement port_change_conduit op
From: Daniel Golle @ 2026-06-15 5:22 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781500517.git.daniel@makrotopia.org>
Allow changing the CPU port affinity of user ports at runtime via the
IFLA_DSA_CONDUIT netlink attribute. This updates the port matrix to
forward to the new CPU port instead of the old one.
Limit the operation to MT7531. There, trapped link-local frames follow
the per-port affinity, as the MT7531_CPU_PMAP destination mask is
further restricted by the port matrix. A conduit change is hence fully
honoured by the hardware, for regular traffic as well as for trapped
frames.
The MT7530 switch, including the variant embedded in the MT7621 SoC,
instead traps frames to the single CPU port set in the CPU_PORT field
of the MFC register, regardless of the affinity of the inbound user
port. With user ports affine to different CPU ports there is no
correct value for that field, so per-port CPU affinity cannot be fully
implemented for trapped frames. Routing a WAN port via the second SoC
GMAC is conventionally covered by the PHY muxing feature on these
switches, which bypasses the switch fabric and does not involve a CPU
port at all.
The switches on the MT7988, EN7581 and AN7583 SoCs only have a
single CPU port, leaving no other conduit to change to.
As the op lives in the shared mt7530_switch_ops, populate the extack
when rejecting the unsupported variants instead of returning a bare
-EOPNOTSUPP. Also reject a conduit that belongs to a different switch
in the tree, whose port index has no meaning in the local port matrix.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Acked-by: Chester A. Unal <chester.a.unal@arinc9.com>
---
v3:
* populate the netlink extack on rejection
* refuse a conduit that lives on a different switch
v2:
* extend commit message
drivers/net/dsa/mt7530.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 98fdd8dcd81c..ef3593353001 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3213,6 +3213,43 @@ static int mt753x_set_mac_eee(struct dsa_switch *ds, int port,
return 0;
}
+static int
+mt753x_port_change_conduit(struct dsa_switch *ds, int port,
+ struct net_device *conduit,
+ struct netlink_ext_ack *extack)
+{
+ struct dsa_port *new_cpu_dp = conduit->dsa_ptr;
+ struct dsa_port *dp = dsa_to_port(ds, port);
+ struct mt7530_priv *priv = ds->priv;
+
+ if (priv->id != ID_MT7531) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Changing DSA conduit is only supported on MT7531");
+ return -EOPNOTSUPP;
+ }
+
+ if (new_cpu_dp->ds != ds) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Cannot assign a conduit on a different switch");
+ return -EOPNOTSUPP;
+ }
+
+ mutex_lock(&priv->reg_mutex);
+
+ /* dp->cpu_dp still points to the old CPU port */
+ priv->ports[port].pm &= ~PCR_MATRIX(BIT(dp->cpu_dp->index));
+ priv->ports[port].pm |= PCR_MATRIX(BIT(new_cpu_dp->index));
+ if (priv->ports[port].enable)
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(port),
+ PCR_MATRIX_MASK, priv->ports[port].pm);
+
+ mutex_unlock(&priv->reg_mutex);
+
+ mt7530_port_fast_age(ds, port);
+
+ return 0;
+}
+
static void
mt753x_conduit_state_change(struct dsa_switch *ds,
const struct net_device *conduit,
@@ -3324,6 +3361,7 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
.setup = mt753x_setup,
.teardown = mt753x_teardown,
.preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port,
+ .port_change_conduit = mt753x_port_change_conduit,
.get_strings = mt7530_get_strings,
.get_ethtool_stats = mt7530_get_ethtool_stats,
.get_sset_count = mt7530_get_sset_count,
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v3 7/8] net: dsa: mt7530: implement port_fast_age
From: Daniel Golle @ 2026-06-15 5:22 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781500517.git.daniel@makrotopia.org>
Implement the .port_fast_age DSA operation by flushing all non-static
(dynamically learned) MAC address entries from the address table.
The switch does not offer a combined "non-static AND per-port" match
mode, so the flush is global and the port argument is not used. Unlike
b53 and realtek, which flush the dynamic entries of the affected port
only, an STP topology change on one port therefore also flushes the
dynamically learned entries of the other ports; they are quickly
relearned.
Access the address table control register under priv->reg_mutex, as done
by all other ATC users (FDB and MDB add/del/dump), to serialise the
write-then-poll command sequence, and log a message should the flush
time out.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3:
* take reg_mutex around the ATC flush and log on timeout
* align the ATC_MAT_NON_STATIC_MAC define
* correct the commit message which wrongly claimed per-port parity
with b53/realtek
v2: no changes
drivers/net/dsa/mt7530.c | 23 +++++++++++++++++++++++
drivers/net/dsa/mt7530.h | 1 +
2 files changed, 24 insertions(+)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 397f5c5e17e5..98fdd8dcd81c 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -193,6 +193,28 @@ mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
return 0;
}
+static void mt7530_port_fast_age(struct dsa_switch *ds, int port)
+{
+ struct mt7530_priv *priv = ds->priv;
+ struct mt7530_dummy_poll p;
+ u32 val;
+ int ret;
+
+ mutex_lock(&priv->reg_mutex);
+
+ /* Flush all non-static MAC address entries */
+ val = ATC_BUSY | ATC_MAT_NON_STATIC_MAC | MT7530_FDB_FLUSH;
+ regmap_write(priv->regmap, MT7530_ATC, val);
+
+ INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_ATC);
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
+ !(val & ATC_BUSY), 20, 20000);
+ if (ret < 0)
+ dev_err(priv->dev, "fast age timeout\n");
+
+ mutex_unlock(&priv->reg_mutex);
+}
+
static void
mt7530_fdb_read(struct mt7530_priv *priv, struct mt7530_fdb *fdb)
{
@@ -3319,6 +3341,7 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
.port_bridge_flags = mt7530_port_bridge_flags,
.port_bridge_join = mt7530_port_bridge_join,
.port_bridge_leave = mt7530_port_bridge_leave,
+ .port_fast_age = mt7530_port_fast_age,
.port_fdb_add = mt7530_port_fdb_add,
.port_fdb_del = mt7530_port_fdb_del,
.port_fdb_dump = mt7530_port_fdb_dump,
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 804c2e0991a0..241e3d460357 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -165,6 +165,7 @@ enum mt753x_to_cpu_fw {
#define ATC_MAT_MASK GENMASK(11, 8)
#define ATC_MAT(x) FIELD_PREP(ATC_MAT_MASK, x)
#define ATC_MAT_MACTAB ATC_MAT(0)
+#define ATC_MAT_NON_STATIC_MAC ATC_MAT(4)
enum mt7530_fdb_cmd {
MT7530_FDB_READ = 0,
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v3 6/8] net: dsa: mt7530: convert to use field accessor macros
From: Daniel Golle @ 2026-06-15 5:21 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781500517.git.daniel@makrotopia.org>
Use FIELD_GET and FIELD_PREP instead of open-coding register fields.
Replace 0x1f constant with (PHY_MAX_ADDR - 1).
Some field macros (ATC_HASH and VTCR_VID) were previously defined as
object-like macros referencing an undeclared 'x' and were therefore
unusable; convert them into proper FIELD_PREP() accessors. The masks are
equivalent to the open-coded values they replace, so there is no
functional change.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3:
* name the age timer field AGE_TIMER_MASK instead of AGE_TIMER_RD_MASK
* note the corrected ATC_HASH/VTCR_VID macros in the commit message
v2: no changes
drivers/net/dsa/mt7530.c | 64 ++++++------
drivers/net/dsa/mt7530.h | 208 ++++++++++++++++++++++-----------------
2 files changed, 148 insertions(+), 124 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index bd4892918f01..397f5c5e17e5 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -208,16 +208,16 @@ mt7530_fdb_read(struct mt7530_priv *priv, struct mt7530_fdb *fdb)
__func__, __LINE__, i, reg[i]);
}
- fdb->vid = (reg[1] >> CVID) & CVID_MASK;
- fdb->aging = (reg[2] >> AGE_TIMER) & AGE_TIMER_MASK;
- fdb->port_mask = (reg[2] >> PORT_MAP) & PORT_MAP_MASK;
- fdb->mac[0] = (reg[0] >> MAC_BYTE_0) & MAC_BYTE_MASK;
- fdb->mac[1] = (reg[0] >> MAC_BYTE_1) & MAC_BYTE_MASK;
- fdb->mac[2] = (reg[0] >> MAC_BYTE_2) & MAC_BYTE_MASK;
- fdb->mac[3] = (reg[0] >> MAC_BYTE_3) & MAC_BYTE_MASK;
- fdb->mac[4] = (reg[1] >> MAC_BYTE_4) & MAC_BYTE_MASK;
- fdb->mac[5] = (reg[1] >> MAC_BYTE_5) & MAC_BYTE_MASK;
- fdb->noarp = ((reg[2] >> ENT_STATUS) & ENT_STATUS_MASK) == STATIC_ENT;
+ fdb->vid = FIELD_GET(CVID_MASK, reg[1]);
+ fdb->aging = FIELD_GET(AGE_TIMER_MASK, reg[2]);
+ fdb->port_mask = FIELD_GET(PORT_MAP_MASK, reg[2]);
+ fdb->mac[0] = FIELD_GET(MAC_BYTE_0_MASK, reg[0]);
+ fdb->mac[1] = FIELD_GET(MAC_BYTE_1_MASK, reg[0]);
+ fdb->mac[2] = FIELD_GET(MAC_BYTE_2_MASK, reg[0]);
+ fdb->mac[3] = FIELD_GET(MAC_BYTE_3_MASK, reg[0]);
+ fdb->mac[4] = FIELD_GET(MAC_BYTE_4_MASK, reg[1]);
+ fdb->mac[5] = FIELD_GET(MAC_BYTE_5_MASK, reg[1]);
+ fdb->noarp = FIELD_GET(ENT_STATUS_MASK, reg[2]) == STATIC_ENT;
}
static void
@@ -228,22 +228,22 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
u32 reg[3] = { 0 };
int i;
- reg[1] |= vid & CVID_MASK;
+ reg[1] |= FIELD_PREP(CVID_MASK, vid);
reg[1] |= ATA2_IVL;
reg[1] |= ATA2_FID(FID_BRIDGED);
- reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER;
- reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP;
+ reg[2] |= FIELD_PREP(AGE_TIMER_MASK, aging);
+ reg[2] |= FIELD_PREP(PORT_MAP_MASK, port_mask);
/* STATIC_ENT indicate that entry is static wouldn't
* be aged out and STATIC_EMP specified as erasing an
* entry
*/
- reg[2] |= (type & ENT_STATUS_MASK) << ENT_STATUS;
- reg[1] |= mac[5] << MAC_BYTE_5;
- reg[1] |= mac[4] << MAC_BYTE_4;
- reg[0] |= mac[3] << MAC_BYTE_3;
- reg[0] |= mac[2] << MAC_BYTE_2;
- reg[0] |= mac[1] << MAC_BYTE_1;
- reg[0] |= mac[0] << MAC_BYTE_0;
+ reg[2] |= FIELD_PREP(ENT_STATUS_MASK, type);
+ reg[1] |= FIELD_PREP(MAC_BYTE_5_MASK, mac[5]);
+ reg[1] |= FIELD_PREP(MAC_BYTE_4_MASK, mac[4]);
+ reg[0] |= FIELD_PREP(MAC_BYTE_3_MASK, mac[3]);
+ reg[0] |= FIELD_PREP(MAC_BYTE_2_MASK, mac[2]);
+ reg[0] |= FIELD_PREP(MAC_BYTE_1_MASK, mac[1]);
+ reg[0] |= FIELD_PREP(MAC_BYTE_0_MASK, mac[0]);
/* Write array into the ARL table */
for (i = 0; i < 3; i++)
@@ -385,22 +385,22 @@ mt7531_pll_setup(struct mt7530_priv *priv)
/* Step 4: program COREPLL output frequency to 500MHz */
regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
- val &= ~RG_COREPLL_POSDIV_M;
- val |= 2 << RG_COREPLL_POSDIV_S;
+ val &= ~RG_COREPLL_POSDIV_MASK;
+ val |= RG_COREPLL_POSDIV(2);
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
usleep_range(25, 35);
switch (xtal) {
case MT7531_XTAL_FSEL_25MHZ:
regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
- val &= ~RG_COREPLL_SDM_PCW_M;
- val |= 0x140000 << RG_COREPLL_SDM_PCW_S;
+ val &= ~RG_COREPLL_SDM_PCW_MASK;
+ val |= RG_COREPLL_SDM_PCW(0x140000);
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
break;
case MT7531_XTAL_FSEL_40MHZ:
regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
- val &= ~RG_COREPLL_SDM_PCW_M;
- val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
+ val &= ~RG_COREPLL_SDM_PCW_MASK;
+ val |= RG_COREPLL_SDM_PCW(0x190000);
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
break;
}
@@ -1555,7 +1555,7 @@ mt7530_vlan_cmd(struct mt7530_priv *priv, enum mt7530_vlan_cmd cmd, u16 vid)
u32 val;
int ret;
- val = VTCR_BUSY | VTCR_FUNC(cmd) | vid;
+ val = VTCR_BUSY | VTCR_FUNC(cmd) | VTCR_VID(vid);
regmap_write(priv->regmap, MT7530_VTCR, val);
INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_VTCR);
@@ -1786,7 +1786,7 @@ mt7530_port_mdb_add(struct dsa_switch *ds, int port,
mt7530_fdb_write(priv, vid, 0, addr, 0, STATIC_EMP);
if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL)) {
regmap_read(priv->regmap, MT7530_ATRD, &val);
- port_mask = (val >> PORT_MAP) & PORT_MAP_MASK;
+ port_mask = FIELD_GET(PORT_MAP_MASK, val);
}
port_mask |= BIT(port);
@@ -1815,7 +1815,7 @@ mt7530_port_mdb_del(struct dsa_switch *ds, int port,
mt7530_fdb_write(priv, vid, 0, addr, 0, STATIC_EMP);
if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL)) {
regmap_read(priv->regmap, MT7530_ATRD, &val);
- port_mask = (val >> PORT_MAP) & PORT_MAP_MASK;
+ port_mask = FIELD_GET(PORT_MAP_MASK, val);
}
port_mask &= ~BIT(port);
@@ -1923,7 +1923,7 @@ mt7530_hw_vlan_update(struct mt7530_priv *priv, u16 vid,
regmap_read(priv->regmap, MT7530_VAWD1, &val);
- entry->old_members = (val >> PORT_MEM_SHFT) & PORT_MEM_MASK;
+ entry->old_members = FIELD_GET(PORT_MEM_MASK, val);
/* Manipulate entry */
vlan_op(priv, entry);
@@ -2436,7 +2436,7 @@ mt7530_setup(struct dsa_switch *ds)
}
regmap_read(priv->regmap, MT7530_CREV, &id);
- id >>= CHIP_NAME_SHIFT;
+ id = FIELD_GET(CHIP_NAME_MASK, id);
if (id != MT7530_ID) {
dev_err(priv->dev, "chip %x can't be supported\n", id);
return -ENODEV;
@@ -2679,7 +2679,7 @@ mt7531_setup(struct dsa_switch *ds)
}
regmap_read(priv->regmap, MT7531_CREV, &id);
- id >>= CHIP_NAME_SHIFT;
+ id = FIELD_GET(CHIP_NAME_MASK, id);
if (id != MT7531_ID) {
dev_err(priv->dev, "chip %x can't be supported\n", id);
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index dd33b0df3419..804c2e0991a0 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -6,6 +6,8 @@
#ifndef __MT7530_H
#define __MT7530_H
+#include <linux/bitfield.h>
+
#define MT7530_NUM_PORTS 7
#define MT7530_NUM_PHYS 5
#define MT7530_NUM_FDB_RECORDS 2048
@@ -146,19 +148,22 @@ enum mt753x_to_cpu_fw {
#define STATIC_ENT 3
#define MT7530_ATA2 0x78
#define ATA2_IVL BIT(15)
-#define ATA2_FID(x) (((x) & 0x7) << 12)
+#define ATA2_FID_MASK GENMASK(14, 12)
+#define ATA2_FID(x) FIELD_PREP(ATA2_FID_MASK, x)
/* Register for address table write data */
#define MT7530_ATWD 0x7c
/* Register for address table control */
#define MT7530_ATC 0x80
-#define ATC_HASH (((x) & 0xfff) << 16)
+#define ATC_HASH_MASK GENMASK(27, 16)
+#define ATC_HASH(x) FIELD_PREP(ATC_HASH_MASK, x)
#define ATC_BUSY BIT(15)
#define ATC_SRCH_END BIT(14)
#define ATC_SRCH_HIT BIT(13)
#define ATC_INVALID BIT(12)
-#define ATC_MAT(x) (((x) & 0xf) << 8)
+#define ATC_MAT_MASK GENMASK(11, 8)
+#define ATC_MAT(x) FIELD_PREP(ATC_MAT_MASK, x)
#define ATC_MAT_MACTAB ATC_MAT(0)
enum mt7530_fdb_cmd {
@@ -171,32 +176,29 @@ enum mt7530_fdb_cmd {
/* Registers for table search read address */
#define MT7530_TSRA1 0x84
-#define MAC_BYTE_0 24
-#define MAC_BYTE_1 16
-#define MAC_BYTE_2 8
-#define MAC_BYTE_3 0
-#define MAC_BYTE_MASK 0xff
+#define MAC_BYTE_0_MASK GENMASK(31, 24)
+#define MAC_BYTE_1_MASK GENMASK(23, 16)
+#define MAC_BYTE_2_MASK GENMASK(15, 8)
+#define MAC_BYTE_3_MASK GENMASK(7, 0)
#define MT7530_TSRA2 0x88
-#define MAC_BYTE_4 24
-#define MAC_BYTE_5 16
-#define CVID 0
-#define CVID_MASK 0xfff
+#define MAC_BYTE_4_MASK GENMASK(31, 24)
+#define MAC_BYTE_5_MASK GENMASK(23, 16)
+#define CVID_MASK GENMASK(11, 0)
#define MT7530_ATRD 0x8C
-#define AGE_TIMER 24
-#define AGE_TIMER_MASK 0xff
-#define PORT_MAP 4
-#define PORT_MAP_MASK 0xff
-#define ENT_STATUS 2
-#define ENT_STATUS_MASK 0x3
+#define AGE_TIMER_MASK GENMASK(31, 24)
+#define PORT_MAP_MASK GENMASK(11, 4)
+#define ENT_STATUS_MASK GENMASK(3, 2)
/* Register for vlan table control */
#define MT7530_VTCR 0x90
#define VTCR_BUSY BIT(31)
#define VTCR_INVALID BIT(16)
-#define VTCR_FUNC(x) (((x) & 0xf) << 12)
-#define VTCR_VID ((x) & 0xfff)
+#define VTCR_FUNC_MASK GENMASK(15, 12)
+#define VTCR_FUNC(x) FIELD_PREP(VTCR_FUNC_MASK, x)
+#define VTCR_VID_MASK GENMASK(11, 0)
+#define VTCR_VID(x) FIELD_PREP(VTCR_VID_MASK, x)
enum mt7530_vlan_cmd {
/* Read/Write the specified VID entry from VAWD register based
@@ -216,13 +218,13 @@ enum mt7530_vlan_cmd {
/* Per VLAN Egress Tag Control */
#define VTAG_EN BIT(28)
/* VLAN Member Control */
-#define PORT_MEM(x) (((x) & 0xff) << 16)
+#define PORT_MEM_MASK GENMASK(23, 16)
+#define PORT_MEM(x) FIELD_PREP(PORT_MEM_MASK, x)
/* Filter ID */
-#define FID(x) (((x) & 0x7) << 1)
+#define FID_MASK GENMASK(3, 1)
+#define FID(x) FIELD_PREP(FID_MASK, x)
/* VLAN Entry Valid */
#define VLAN_VALID BIT(0)
-#define PORT_MEM_SHFT 16
-#define PORT_MEM_MASK 0xff
enum mt7530_fid {
FID_STANDALONE = 0,
@@ -247,11 +249,11 @@ enum mt7530_vlan_egress_attr {
/* Age count */
#define AGE_CNT_MASK GENMASK(19, 12)
#define AGE_CNT_MAX 0xff
-#define AGE_CNT(x) (AGE_CNT_MASK & ((x) << 12))
+#define AGE_CNT(x) FIELD_PREP(AGE_CNT_MASK, x)
/* Age unit */
#define AGE_UNIT_MASK GENMASK(11, 0)
#define AGE_UNIT_MAX 0xfff
-#define AGE_UNIT(x) (AGE_UNIT_MASK & (x))
+#define AGE_UNIT(x) FIELD_PREP(AGE_UNIT_MASK, x)
#define MT753X_ERLCR_P(x) (0x1040 + ((x) * 0x100))
#define ERLCR_CIR_MASK GENMASK(31, 16)
@@ -282,30 +284,31 @@ enum mt7530_stp_state {
#define MT7530_PCR_P(x) (0x2004 + ((x) * 0x100))
#define PORT_TX_MIR BIT(9)
#define PORT_RX_MIR BIT(8)
-#define PORT_VLAN(x) ((x) & 0x3)
+#define PCR_PORT_VLAN_MASK GENMASK(1, 0)
enum mt7530_port_mode {
/* Port Matrix Mode: Frames are forwarded by the PCR_MATRIX members. */
- MT7530_PORT_MATRIX_MODE = PORT_VLAN(0),
+ MT7530_PORT_MATRIX_MODE = 0,
/* Fallback Mode: Forward received frames with ingress ports that do
* not belong to the VLAN member. Frames whose VID is not listed on
* the VLAN table are forwarded by the PCR_MATRIX members.
*/
- MT7530_PORT_FALLBACK_MODE = PORT_VLAN(1),
+ MT7530_PORT_FALLBACK_MODE = 1,
/* Security Mode: Discard any frame due to ingress membership
* violation or VID missed on the VLAN table.
*/
- MT7530_PORT_SECURITY_MODE = PORT_VLAN(3),
+ MT7530_PORT_SECURITY_MODE = 3,
};
-#define PCR_MATRIX(x) (((x) & 0xff) << 16)
-#define PORT_PRI(x) (((x) & 0x7) << 24)
-#define EG_TAG(x) (((x) & 0x3) << 28)
-#define PCR_MATRIX_MASK PCR_MATRIX(0xff)
+#define PCR_MATRIX_MASK GENMASK(23, 16)
+#define PCR_MATRIX(x) FIELD_PREP(PCR_MATRIX_MASK, x)
+#define PORT_PRI_MASK GENMASK(26, 24)
+#define PORT_PRI(x) FIELD_PREP(PORT_PRI_MASK, x)
+#define EG_TAG_MASK GENMASK(29, 28)
+#define EG_TAG(x) FIELD_PREP(EG_TAG_MASK, x)
#define PCR_MATRIX_CLR PCR_MATRIX(0)
-#define PCR_PORT_VLAN_MASK PORT_VLAN(3)
/* Register for port security control */
#define MT7530_PSC_P(x) (0x200c + ((x) * 0x100))
@@ -314,10 +317,10 @@ enum mt7530_port_mode {
/* Register for port vlan control */
#define MT7530_PVC_P(x) (0x2010 + ((x) * 0x100))
#define PORT_SPEC_TAG BIT(5)
-#define PVC_EG_TAG(x) (((x) & 0x7) << 8)
-#define PVC_EG_TAG_MASK PVC_EG_TAG(7)
-#define VLAN_ATTR(x) (((x) & 0x3) << 6)
-#define VLAN_ATTR_MASK VLAN_ATTR(3)
+#define PVC_EG_TAG_MASK GENMASK(10, 8)
+#define PVC_EG_TAG(x) FIELD_PREP(PVC_EG_TAG_MASK, x)
+#define VLAN_ATTR_MASK GENMASK(7, 6)
+#define VLAN_ATTR(x) FIELD_PREP(VLAN_ATTR_MASK, x)
#define ACC_FRM_MASK GENMASK(1, 0)
enum mt7530_vlan_port_eg_tag {
@@ -337,12 +340,13 @@ enum mt7530_vlan_port_acc_frm {
MT7530_VLAN_ACC_UNTAGGED = 2,
};
-#define STAG_VPID (((x) & 0xffff) << 16)
+#define STAG_VPID_MASK GENMASK(31, 16)
+#define STAG_VPID(x) FIELD_PREP(STAG_VPID_MASK, x)
/* Register for port port-and-protocol based vlan 1 control */
#define MT7530_PPBV1_P(x) (0x2014 + ((x) * 0x100))
-#define G0_PORT_VID(x) (((x) & 0xfff) << 0)
-#define G0_PORT_VID_MASK G0_PORT_VID(0xfff)
+#define G0_PORT_VID_MASK GENMASK(11, 0)
+#define G0_PORT_VID(x) FIELD_PREP(G0_PORT_VID_MASK, x)
#define G0_PORT_VID_DEF G0_PORT_VID(0)
/* Register for port MAC control register */
@@ -418,8 +422,8 @@ enum mt7530_vlan_port_acc_frm {
#define MT7531_DIS_CLR BIT(31)
#define MT7530_GMACCR 0x30e0
-#define MAX_RX_JUMBO(x) ((x) << 2)
#define MAX_RX_JUMBO_MASK GENMASK(5, 2)
+#define MAX_RX_JUMBO(x) FIELD_PREP(MAX_RX_JUMBO_MASK, x)
#define MAX_RX_PKT_LEN_MASK GENMASK(1, 0)
#define MAX_RX_PKT_LEN_1522 0x0
#define MAX_RX_PKT_LEN_1536 0x1
@@ -505,16 +509,16 @@ enum mt7530_vlan_port_acc_frm {
/* Register for PHY Indirect Access Control */
#define MT7531_PHY_IAC 0x701C
#define MT7531_PHY_ACS_ST BIT(31)
-#define MT7531_MDIO_REG_ADDR_MASK (0x1f << 25)
-#define MT7531_MDIO_PHY_ADDR_MASK (0x1f << 20)
-#define MT7531_MDIO_CMD_MASK (0x3 << 18)
-#define MT7531_MDIO_ST_MASK (0x3 << 16)
-#define MT7531_MDIO_RW_DATA_MASK (0xffff)
-#define MT7531_MDIO_REG_ADDR(x) (((x) & 0x1f) << 25)
-#define MT7531_MDIO_DEV_ADDR(x) (((x) & 0x1f) << 25)
-#define MT7531_MDIO_PHY_ADDR(x) (((x) & 0x1f) << 20)
-#define MT7531_MDIO_CMD(x) (((x) & 0x3) << 18)
-#define MT7531_MDIO_ST(x) (((x) & 0x3) << 16)
+#define MT7531_MDIO_REG_ADDR_MASK GENMASK(29, 25)
+#define MT7531_MDIO_PHY_ADDR_MASK GENMASK(24, 20)
+#define MT7531_MDIO_CMD_MASK GENMASK(19, 18)
+#define MT7531_MDIO_ST_MASK GENMASK(17, 16)
+#define MT7531_MDIO_RW_DATA_MASK GENMASK(15, 0)
+#define MT7531_MDIO_REG_ADDR(x) FIELD_PREP(MT7531_MDIO_REG_ADDR_MASK, x)
+#define MT7531_MDIO_DEV_ADDR(x) FIELD_PREP(MT7531_MDIO_REG_ADDR_MASK, x)
+#define MT7531_MDIO_PHY_ADDR(x) FIELD_PREP(MT7531_MDIO_PHY_ADDR_MASK, x)
+#define MT7531_MDIO_CMD(x) FIELD_PREP(MT7531_MDIO_CMD_MASK, x)
+#define MT7531_MDIO_ST(x) FIELD_PREP(MT7531_MDIO_ST_MASK, x)
enum mt7531_phy_iac_cmd {
MT7531_MDIO_ADDR = 0,
@@ -542,14 +546,14 @@ enum mt7531_mdio_st {
/* Register for RGMII clock phase */
#define MT7531_CLKGEN_CTRL 0x7500
-#define CLK_SKEW_OUT(x) (((x) & 0x3) << 8)
#define CLK_SKEW_OUT_MASK GENMASK(9, 8)
-#define CLK_SKEW_IN(x) (((x) & 0x3) << 6)
+#define CLK_SKEW_OUT(x) FIELD_PREP(CLK_SKEW_OUT_MASK, x)
#define CLK_SKEW_IN_MASK GENMASK(7, 6)
+#define CLK_SKEW_IN(x) FIELD_PREP(CLK_SKEW_IN_MASK, x)
#define RXCLK_NO_DELAY BIT(5)
#define TXCLK_NO_REVERSE BIT(4)
-#define GP_MODE(x) (((x) & 0x3) << 1)
#define GP_MODE_MASK GENMASK(2, 1)
+#define GP_MODE(x) FIELD_PREP(GP_MODE_MASK, x)
#define GP_CLK_EN BIT(0)
enum mt7531_gp_mode {
@@ -599,8 +603,10 @@ enum mt7531_xtal_fsel {
#define PAD_MCM_SMI_EN BIT(0)
#define MT7530_IO_DRV_CR 0x7810
-#define P5_IO_CLK_DRV(x) ((x) & 0x3)
-#define P5_IO_DATA_DRV(x) (((x) & 0x3) << 4)
+#define P5_IO_CLK_DRV_MASK GENMASK(1, 0)
+#define P5_IO_CLK_DRV(x) FIELD_PREP(P5_IO_CLK_DRV_MASK, x)
+#define P5_IO_DATA_DRV_MASK GENMASK(5, 4)
+#define P5_IO_DATA_DRV(x) FIELD_PREP(P5_IO_DATA_DRV_MASK, x)
#define MT7531_CHIP_REV 0x781C
@@ -610,15 +616,15 @@ enum mt7531_xtal_fsel {
#define SW_PLLGP BIT(0)
#define MT7530_P6ECR 0x7830
-#define P6_INTF_MODE_MASK 0x3
-#define P6_INTF_MODE(x) ((x) & 0x3)
+#define P6_INTF_MODE_MASK GENMASK(1, 0)
+#define P6_INTF_MODE(x) FIELD_PREP(P6_INTF_MODE_MASK, x)
#define MT7531_PLLGP_CR0 0x78a8
#define RG_COREPLL_EN BIT(22)
-#define RG_COREPLL_POSDIV_S 23
-#define RG_COREPLL_POSDIV_M 0x3800000
-#define RG_COREPLL_SDM_PCW_S 1
-#define RG_COREPLL_SDM_PCW_M 0x3ffffe
+#define RG_COREPLL_POSDIV_MASK GENMASK(25, 23)
+#define RG_COREPLL_POSDIV(x) FIELD_PREP(RG_COREPLL_POSDIV_MASK, x)
+#define RG_COREPLL_SDM_PCW_MASK GENMASK(21, 1)
+#define RG_COREPLL_SDM_PCW(x) FIELD_PREP(RG_COREPLL_SDM_PCW_MASK, x)
#define RG_COREPLL_SDM_PCW_CHG BIT(0)
/* Registers for RGMII and SGMII PLL clock */
@@ -629,10 +635,10 @@ enum mt7531_xtal_fsel {
#define MT7530_TRGMII_RCK_CTRL 0x7a00
#define RX_RST BIT(31)
#define RXC_DQSISEL BIT(30)
-#define DQSI1_TAP_MASK (0x7f << 8)
-#define DQSI0_TAP_MASK 0x7f
-#define DQSI1_TAP(x) (((x) & 0x7f) << 8)
-#define DQSI0_TAP(x) ((x) & 0x7f)
+#define DQSI1_TAP_MASK GENMASK(14, 8)
+#define DQSI0_TAP_MASK GENMASK(6, 0)
+#define DQSI1_TAP(x) FIELD_PREP(DQSI1_TAP_MASK, x)
+#define DQSI0_TAP(x) FIELD_PREP(DQSI0_TAP_MASK, x)
#define MT7530_TRGMII_RCK_RTT 0x7a04
#define DQS1_GATE BIT(31)
@@ -641,8 +647,8 @@ enum mt7531_xtal_fsel {
#define MT7530_TRGMII_RD(x) (0x7a10 + (x) * 8)
#define BSLIP_EN BIT(31)
#define EDGE_CHK BIT(30)
-#define RD_TAP_MASK 0x7f
-#define RD_TAP(x) ((x) & 0x7f)
+#define RD_TAP_MASK GENMASK(6, 0)
+#define RD_TAP(x) FIELD_PREP(RD_TAP_MASK, x)
#define MT7530_TRGMII_TXCTRL 0x7a40
#define TRAIN_TXEN BIT(31)
@@ -650,18 +656,23 @@ enum mt7531_xtal_fsel {
#define TX_RST BIT(28)
#define MT7530_TRGMII_TD_ODT(i) (0x7a54 + 8 * (i))
-#define TD_DM_DRVP(x) ((x) & 0xf)
-#define TD_DM_DRVN(x) (((x) & 0xf) << 4)
+#define TD_DM_DRVP_MASK GENMASK(3, 0)
+#define TD_DM_DRVP(x) FIELD_PREP(TD_DM_DRVP_MASK, x)
+#define TD_DM_DRVN_MASK GENMASK(7, 4)
+#define TD_DM_DRVN(x) FIELD_PREP(TD_DM_DRVN_MASK, x)
#define MT7530_TRGMII_TCK_CTRL 0x7a78
-#define TCK_TAP(x) (((x) & 0xf) << 8)
+#define TCK_TAP_MASK GENMASK(11, 8)
+#define TCK_TAP(x) FIELD_PREP(TCK_TAP_MASK, x)
#define MT7530_P5RGMIIRXCR 0x7b00
#define CSR_RGMII_EDGE_ALIGN BIT(8)
-#define CSR_RGMII_RXC_0DEG_CFG(x) ((x) & 0xf)
+#define CSR_RGMII_RXC_0DEG_CFG_MASK GENMASK(3, 0)
+#define CSR_RGMII_RXC_0DEG_CFG(x) FIELD_PREP(CSR_RGMII_RXC_0DEG_CFG_MASK, x)
#define MT7530_P5RGMIITXCR 0x7b04
-#define CSR_RGMII_TXC_CFG(x) ((x) & 0x1f)
+#define CSR_RGMII_TXC_CFG_MASK GENMASK(4, 0)
+#define CSR_RGMII_TXC_CFG(x) FIELD_PREP(CSR_RGMII_TXC_CFG_MASK, x)
/* Registers for GPIO mode */
#define MT7531_GPIO_MODE0 0x7c0c
@@ -670,9 +681,9 @@ enum mt7531_xtal_fsel {
#define MT7531_GPIO_MODE1 0x7c10
#define MT7531_GPIO11_RG_RXD2_MASK GENMASK(15, 12)
-#define MT7531_EXT_P_MDC_11 (2 << 12)
+#define MT7531_EXT_P_MDC_11 FIELD_PREP(MT7531_GPIO11_RG_RXD2_MASK, 2)
#define MT7531_GPIO12_RG_RXD3_MASK GENMASK(19, 16)
-#define MT7531_EXT_P_MDIO_12 (2 << 16)
+#define MT7531_EXT_P_MDIO_12 FIELD_PREP(MT7531_GPIO12_RG_RXD3_MASK, 2)
#define MT753X_CPORT_SPTAG_CFG 0x7c10
#define CPORT_SW2FE_STAG_EN BIT(1)
@@ -704,7 +715,7 @@ enum mt7531_xtal_fsel {
#define MT7530_LED_GPIO_DATA 0x7d18
#define MT7530_CREV 0x7ffc
-#define CHIP_NAME_SHIFT 16
+#define CHIP_NAME_MASK GENMASK(31, 16)
#define MT7530_ID 0x7530
#define MT7531_CREV 0x781C
@@ -716,10 +727,13 @@ enum mt7531_xtal_fsel {
#define RG_SYSPLL_EN_NORMAL BIT(15)
#define RG_SYSPLL_VODEN BIT(14)
#define RG_SYSPLL_LF BIT(13)
-#define RG_SYSPLL_RST_DLY(x) (((x) & 0x3) << 12)
+#define RG_SYSPLL_RST_DLY_MASK GENMASK(13, 12)
+#define RG_SYSPLL_RST_DLY(x) FIELD_PREP(RG_SYSPLL_RST_DLY_MASK, x)
#define RG_SYSPLL_LVROD_EN BIT(10)
-#define RG_SYSPLL_PREDIV(x) (((x) & 0x3) << 8)
-#define RG_SYSPLL_POSDIV(x) (((x) & 0x3) << 5)
+#define RG_SYSPLL_PREDIV_MASK GENMASK(9, 8)
+#define RG_SYSPLL_PREDIV(x) FIELD_PREP(RG_SYSPLL_PREDIV_MASK, x)
+#define RG_SYSPLL_POSDIV_MASK GENMASK(6, 5)
+#define RG_SYSPLL_POSDIV(x) FIELD_PREP(RG_SYSPLL_POSDIV_MASK, x)
#define RG_SYSPLL_FBKSEL BIT(4)
#define RT_SYSPLL_EN_AFE_OLT BIT(0)
@@ -731,38 +745,48 @@ enum mt7531_xtal_fsel {
#define MT7531_PHY_PLL_OFF BIT(5)
#define MT7531_PHY_PLL_BYPASS_MODE BIT(4)
-#define MT753X_CTRL_PHY_ADDR(addr) ((addr + 1) & 0x1f)
+#define MT753X_CTRL_PHY_ADDR(addr) (((addr) + 1) & (PHY_MAX_ADDR - 1))
#define CORE_PLL_GROUP5 0x404
-#define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff)
+#define RG_LCDDS_PCW_NCPO1_MASK GENMASK(15, 0)
+#define RG_LCDDS_PCW_NCPO1(x) FIELD_PREP(RG_LCDDS_PCW_NCPO1_MASK, x)
#define CORE_PLL_GROUP6 0x405
-#define RG_LCDDS_PCW_NCPO0(x) ((x) & 0xffff)
+#define RG_LCDDS_PCW_NCPO0_MASK GENMASK(15, 0)
+#define RG_LCDDS_PCW_NCPO0(x) FIELD_PREP(RG_LCDDS_PCW_NCPO0_MASK, x)
#define CORE_PLL_GROUP7 0x406
#define RG_LCDDS_PWDB BIT(15)
#define RG_LCDDS_ISO_EN BIT(13)
-#define RG_LCCDS_C(x) (((x) & 0x7) << 4)
+#define RG_LCCDS_C_MASK GENMASK(6, 4)
+#define RG_LCCDS_C(x) FIELD_PREP(RG_LCCDS_C_MASK, x)
#define RG_LCDDS_PCW_NCPO_CHG BIT(3)
#define CORE_PLL_GROUP10 0x409
-#define RG_LCDDS_SSC_DELTA(x) ((x) & 0xfff)
+#define RG_LCDDS_SSC_DELTA_MASK GENMASK(11, 0)
+#define RG_LCDDS_SSC_DELTA(x) FIELD_PREP(RG_LCDDS_SSC_DELTA_MASK, x)
#define CORE_PLL_GROUP11 0x40a
-#define RG_LCDDS_SSC_DELTA1(x) ((x) & 0xfff)
+#define RG_LCDDS_SSC_DELTA1_MASK GENMASK(11, 0)
+#define RG_LCDDS_SSC_DELTA1(x) FIELD_PREP(RG_LCDDS_SSC_DELTA1_MASK, x)
#define CORE_GSWPLL_GRP1 0x40d
-#define RG_GSWPLL_PREDIV(x) (((x) & 0x3) << 14)
-#define RG_GSWPLL_POSDIV_200M(x) (((x) & 0x3) << 12)
+#define RG_GSWPLL_PREDIV_MASK GENMASK(15, 14)
+#define RG_GSWPLL_PREDIV(x) FIELD_PREP(RG_GSWPLL_PREDIV_MASK, x)
+#define RG_GSWPLL_POSDIV_200M_MASK GENMASK(13, 12)
+#define RG_GSWPLL_POSDIV_200M(x) FIELD_PREP(RG_GSWPLL_POSDIV_200M_MASK, x)
#define RG_GSWPLL_EN_PRE BIT(11)
#define RG_GSWPLL_FBKSEL BIT(10)
#define RG_GSWPLL_BP BIT(9)
#define RG_GSWPLL_BR BIT(8)
-#define RG_GSWPLL_FBKDIV_200M(x) ((x) & 0xff)
+#define RG_GSWPLL_FBKDIV_200M_MASK GENMASK(7, 0)
+#define RG_GSWPLL_FBKDIV_200M(x) FIELD_PREP(RG_GSWPLL_FBKDIV_200M_MASK, x)
#define CORE_GSWPLL_GRP2 0x40e
-#define RG_GSWPLL_POSDIV_500M(x) (((x) & 0x3) << 8)
-#define RG_GSWPLL_FBKDIV_500M(x) ((x) & 0xff)
+#define RG_GSWPLL_POSDIV_500M_MASK GENMASK(9, 8)
+#define RG_GSWPLL_POSDIV_500M(x) FIELD_PREP(RG_GSWPLL_POSDIV_500M_MASK, x)
+#define RG_GSWPLL_FBKDIV_500M_MASK GENMASK(7, 0)
+#define RG_GSWPLL_FBKDIV_500M(x) FIELD_PREP(RG_GSWPLL_FBKDIV_500M_MASK, x)
#define CORE_TRGMII_GSW_CLK_CG 0x410
#define REG_GSWCK_EN BIT(0)
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v3 5/8] net: dsa: mt7530: replace mt7530_read with regmap_read
From: Daniel Golle @ 2026-06-15 5:21 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781500517.git.daniel@makrotopia.org>
Replace all mt7530_read() calls with direct regmap_read() calls and
remove the wrapper function. The WARN_ON_ONCE error logging is dropped
as regmap provides its own error handling.
Most callsites follow the val = mt7530_read(priv, reg) pattern and are
converted mechanically using the following semantic patch:
@@
expression priv, reg;
identifier val;
@@
-val = mt7530_read(priv, reg);
+regmap_read(priv->regmap, reg, &val);
Remaining inline uses are converted by hand.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3:
* init read-back variables to 0 to preserve the old read-failure
behaviour
* use u32 for val in mt7530_setup_port5
v2:
* drop fix for stray 'static void' leftover now correctly squashed
into 4/8
drivers/net/dsa/mt7530.c | 129 +++++++++++++++++++--------------------
1 file changed, 64 insertions(+), 65 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index fe7e4ab5ae9c..bd4892918f01 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -152,28 +152,15 @@ core_clear(struct mt7530_priv *priv, u32 reg, u32 val)
static u32
-mt7530_read(struct mt7530_priv *priv, u32 reg)
+mt7530_mii_poll(struct mt7530_dummy_poll *p)
{
- int ret;
- u32 val;
+ u32 val = 0;
- ret = regmap_read(priv->regmap, reg, &val);
- if (ret) {
- WARN_ON_ONCE(1);
- dev_err(priv->dev,
- "failed to read mt7530 register\n");
- return 0;
- }
+ regmap_read(p->priv->regmap, p->reg, &val);
return val;
}
-static u32
-mt7530_mii_poll(struct mt7530_dummy_poll *p)
-{
- return mt7530_read(p->priv, p->reg);
-}
-
static int
mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
{
@@ -196,7 +183,7 @@ mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
/* Additional sanity for read command if the specified
* entry is invalid
*/
- val = mt7530_read(priv, MT7530_ATC);
+ regmap_read(priv->regmap, MT7530_ATC, &val);
if ((cmd == MT7530_FDB_READ) && (val & ATC_INVALID))
return -EINVAL;
@@ -214,7 +201,8 @@ mt7530_fdb_read(struct mt7530_priv *priv, struct mt7530_fdb *fdb)
/* Read from ARL table into an array */
for (i = 0; i < 3; i++) {
- reg[i] = mt7530_read(priv, MT7530_TSRA1 + (i * 4));
+ regmap_read(priv->regmap, MT7530_TSRA1 + (i * 4),
+ ®[i]);
dev_dbg(priv->dev, "%s(%d) reg[%d]=0x%x\n",
__func__, __LINE__, i, reg[i]);
@@ -321,7 +309,8 @@ mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
regmap_update_bits(priv->regmap, MT7530_P6ECR, P6_INTF_MODE_MASK,
P6_INTF_MODE(1));
- xtal = mt7530_read(priv, MT753X_MTRAP) & MT7530_XTAL_MASK;
+ regmap_read(priv->regmap, MT753X_MTRAP, &xtal);
+ xtal &= MT7530_XTAL_MASK;
if (xtal == MT7530_XTAL_25MHZ)
ssc_delta = 0x57;
@@ -361,13 +350,13 @@ static void
mt7531_pll_setup(struct mt7530_priv *priv)
{
enum mt7531_xtal_fsel xtal;
- u32 top_sig;
- u32 hwstrap;
- u32 val;
+ u32 top_sig = 0;
+ u32 hwstrap = 0;
+ u32 val = 0;
- val = mt7530_read(priv, MT7531_CREV);
- top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR);
- hwstrap = mt7530_read(priv, MT753X_TRAP);
+ regmap_read(priv->regmap, MT7531_CREV, &val);
+ regmap_read(priv->regmap, MT7531_TOP_SIG_SR, &top_sig);
+ regmap_read(priv->regmap, MT753X_TRAP, &hwstrap);
if ((val & CHIP_REV_M) > 0)
xtal = (top_sig & PAD_MCM_SMI_EN) ? MT7531_XTAL_FSEL_40MHZ :
MT7531_XTAL_FSEL_25MHZ;
@@ -376,26 +365,26 @@ mt7531_pll_setup(struct mt7530_priv *priv)
MT7531_XTAL_FSEL_40MHZ;
/* Step 1 : Disable MT7531 COREPLL */
- val = mt7530_read(priv, MT7531_PLLGP_EN);
+ regmap_read(priv->regmap, MT7531_PLLGP_EN, &val);
val &= ~EN_COREPLL;
regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
/* Step 2: switch to XTAL output */
- val = mt7530_read(priv, MT7531_PLLGP_EN);
+ regmap_read(priv->regmap, MT7531_PLLGP_EN, &val);
val |= SW_CLKSW;
regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val &= ~RG_COREPLL_EN;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
/* Step 3: disable PLLGP and enable program PLLGP */
- val = mt7530_read(priv, MT7531_PLLGP_EN);
+ regmap_read(priv->regmap, MT7531_PLLGP_EN, &val);
val |= SW_PLLGP;
regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
/* Step 4: program COREPLL output frequency to 500MHz */
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val &= ~RG_COREPLL_POSDIV_M;
val |= 2 << RG_COREPLL_POSDIV_S;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
@@ -403,13 +392,13 @@ mt7531_pll_setup(struct mt7530_priv *priv)
switch (xtal) {
case MT7531_XTAL_FSEL_25MHZ:
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val &= ~RG_COREPLL_SDM_PCW_M;
val |= 0x140000 << RG_COREPLL_SDM_PCW_S;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
break;
case MT7531_XTAL_FSEL_40MHZ:
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val &= ~RG_COREPLL_SDM_PCW_M;
val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
@@ -417,14 +406,14 @@ mt7531_pll_setup(struct mt7530_priv *priv)
}
/* Set feedback divide ratio update signal to high */
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val |= RG_COREPLL_SDM_PCW_CHG;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
/* Wait for at least 16 XTAL clocks */
usleep_range(10, 20);
/* Step 5: set feedback divide ratio update signal to low */
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val &= ~RG_COREPLL_SDM_PCW_CHG;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
@@ -435,11 +424,11 @@ mt7531_pll_setup(struct mt7530_priv *priv)
regmap_write(priv->regmap, MT7531_ANA_PLLGP_CR2, 0x4f40000);
/* Step 6: Enable MT7531 PLL */
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val |= RG_COREPLL_EN;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
- val = mt7530_read(priv, MT7531_PLLGP_EN);
+ regmap_read(priv->regmap, MT7531_PLLGP_EN, &val);
val |= EN_COREPLL;
regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
usleep_range(25, 35);
@@ -696,13 +685,13 @@ static void
mt7530_read_port_stats(struct mt7530_priv *priv, int port,
u32 offset, u8 size, uint64_t *data)
{
- u32 val, reg = MT7530_PORT_MIB_COUNTER(port) + offset;
+ u32 val = 0, reg = MT7530_PORT_MIB_COUNTER(port) + offset;
- val = mt7530_read(priv, reg);
+ regmap_read(priv->regmap, reg, &val);
*data = val;
if (size == 2) {
- val = mt7530_read(priv, reg + 4);
+ regmap_read(priv->regmap, reg + 4, &val);
*data |= (u64)val << 32;
}
}
@@ -1006,11 +995,11 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
{
struct mt7530_priv *priv = ds->priv;
u8 tx_delay = 0;
- int val;
+ u32 val;
mutex_lock(&priv->reg_mutex);
- val = mt7530_read(priv, MT753X_MTRAP);
+ regmap_read(priv->regmap, MT753X_MTRAP, &val);
val &= ~MT7530_P5_PHY0_SEL & ~MT7530_P5_MAC_SEL & ~MT7530_P5_RGMII_MODE;
@@ -1368,8 +1357,8 @@ static int
mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
{
struct mt7530_priv *priv = ds->priv;
+ u32 val = 0;
int length;
- u32 val;
/* When a new MTU is set, DSA always set the CPU port's MTU to the
* largest MTU of the user ports. Because the switch only has a global
@@ -1378,7 +1367,7 @@ mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
if (!dsa_is_cpu_port(ds, port))
return 0;
- val = mt7530_read(priv, MT7530_GMACCR);
+ regmap_read(priv->regmap, MT7530_GMACCR, &val);
val &= ~MAX_RX_PKT_LEN_MASK;
/* RX length also includes Ethernet header, MTK tag, and FCS length */
@@ -1577,7 +1566,7 @@ mt7530_vlan_cmd(struct mt7530_priv *priv, enum mt7530_vlan_cmd cmd, u16 vid)
return ret;
}
- val = mt7530_read(priv, MT7530_VTCR);
+ regmap_read(priv->regmap, MT7530_VTCR, &val);
if (val & VTCR_INVALID) {
dev_err(priv->dev, "read VTCR invalid\n");
return -EINVAL;
@@ -1789,14 +1778,16 @@ mt7530_port_mdb_add(struct dsa_switch *ds, int port,
const u8 *addr = mdb->addr;
u16 vid = mdb->vid;
u8 port_mask = 0;
+ u32 val;
int ret;
mutex_lock(&priv->reg_mutex);
mt7530_fdb_write(priv, vid, 0, addr, 0, STATIC_EMP);
- if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL))
- port_mask = (mt7530_read(priv, MT7530_ATRD) >> PORT_MAP)
- & PORT_MAP_MASK;
+ if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL)) {
+ regmap_read(priv->regmap, MT7530_ATRD, &val);
+ port_mask = (val >> PORT_MAP) & PORT_MAP_MASK;
+ }
port_mask |= BIT(port);
mt7530_fdb_write(priv, vid, port_mask, addr, -1, STATIC_ENT);
@@ -1816,14 +1807,16 @@ mt7530_port_mdb_del(struct dsa_switch *ds, int port,
const u8 *addr = mdb->addr;
u16 vid = mdb->vid;
u8 port_mask = 0;
+ u32 val;
int ret;
mutex_lock(&priv->reg_mutex);
mt7530_fdb_write(priv, vid, 0, addr, 0, STATIC_EMP);
- if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL))
- port_mask = (mt7530_read(priv, MT7530_ATRD) >> PORT_MAP)
- & PORT_MAP_MASK;
+ if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL)) {
+ regmap_read(priv->regmap, MT7530_ATRD, &val);
+ port_mask = (val >> PORT_MAP) & PORT_MAP_MASK;
+ }
port_mask &= ~BIT(port);
mt7530_fdb_write(priv, vid, port_mask, addr, -1,
@@ -1901,7 +1894,7 @@ mt7530_hw_vlan_del(struct mt7530_priv *priv,
new_members = entry->old_members & ~BIT(entry->port);
- val = mt7530_read(priv, MT7530_VAWD1);
+ regmap_read(priv->regmap, MT7530_VAWD1, &val);
if (!(val & VLAN_VALID)) {
dev_err(priv->dev,
"Cannot be deleted due to invalid entry\n");
@@ -1928,7 +1921,7 @@ mt7530_hw_vlan_update(struct mt7530_priv *priv, u16 vid,
/* Fetch entry */
mt7530_vlan_cmd(priv, MT7530_VTCR_RD_VID, vid);
- val = mt7530_read(priv, MT7530_VAWD1);
+ regmap_read(priv->regmap, MT7530_VAWD1, &val);
entry->old_members = (val >> PORT_MEM_SHFT) & PORT_MEM_MASK;
@@ -2046,7 +2039,7 @@ static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
return -EEXIST;
- val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id));
+ regmap_read(priv->regmap, MT753X_MIRROR_REG(priv->id), &val);
/* MT7530 only supports one monitor port */
monitor_port = MT753X_MIRROR_PORT_GET(priv->id, val);
@@ -2059,7 +2052,7 @@ static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
val |= MT753X_MIRROR_PORT_SET(priv->id, mirror->to_local_port);
regmap_write(priv->regmap, MT753X_MIRROR_REG(priv->id), val);
- val = mt7530_read(priv, MT7530_PCR_P(port));
+ regmap_read(priv->regmap, MT7530_PCR_P(port), &val);
if (ingress) {
val |= PORT_RX_MIR;
priv->mirror_rx |= BIT(port);
@@ -2076,9 +2069,9 @@ static void mt753x_port_mirror_del(struct dsa_switch *ds, int port,
struct dsa_mall_mirror_tc_entry *mirror)
{
struct mt7530_priv *priv = ds->priv;
- u32 val;
+ u32 val = 0;
- val = mt7530_read(priv, MT7530_PCR_P(port));
+ regmap_read(priv->regmap, MT7530_PCR_P(port), &val);
if (mirror->ingress) {
val &= ~PORT_RX_MIR;
priv->mirror_rx &= ~BIT(port);
@@ -2089,7 +2082,7 @@ static void mt753x_port_mirror_del(struct dsa_switch *ds, int port,
regmap_write(priv->regmap, MT7530_PCR_P(port), val);
if (!priv->mirror_rx && !priv->mirror_tx) {
- val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id));
+ regmap_read(priv->regmap, MT753X_MIRROR_REG(priv->id), &val);
val &= ~MT753X_MIRROR_EN(priv->id);
regmap_write(priv->regmap, MT753X_MIRROR_REG(priv->id), val);
}
@@ -2121,8 +2114,11 @@ mt7530_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
struct mt7530_priv *priv = gpiochip_get_data(gc);
u32 bit = mt7530_gpio_to_bit(offset);
+ u32 val = 0;
+
+ regmap_read(priv->regmap, MT7530_LED_GPIO_DATA, &val);
- return !!(mt7530_read(priv, MT7530_LED_GPIO_DATA) & bit);
+ return !!(val & bit);
}
static int
@@ -2144,8 +2140,11 @@ mt7530_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
struct mt7530_priv *priv = gpiochip_get_data(gc);
u32 bit = mt7530_gpio_to_bit(offset);
+ u32 val;
+
+ regmap_read(priv->regmap, MT7530_LED_GPIO_DIR, &val);
- return (mt7530_read(priv, MT7530_LED_GPIO_DIR) & bit) ?
+ return (val & bit) ?
GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
}
@@ -2436,7 +2435,7 @@ mt7530_setup(struct dsa_switch *ds)
return ret;
}
- id = mt7530_read(priv, MT7530_CREV);
+ regmap_read(priv->regmap, MT7530_CREV, &id);
id >>= CHIP_NAME_SHIFT;
if (id != MT7530_ID) {
dev_err(priv->dev, "chip %x can't be supported\n", id);
@@ -2679,7 +2678,7 @@ mt7531_setup(struct dsa_switch *ds)
return ret;
}
- id = mt7530_read(priv, MT7531_CREV);
+ regmap_read(priv->regmap, MT7531_CREV, &id);
id >>= CHIP_NAME_SHIFT;
if (id != MT7531_ID) {
@@ -2690,7 +2689,7 @@ mt7531_setup(struct dsa_switch *ds)
/* MT7531AE has got two SGMII units. One for port 5, one for port 6.
* MT7531BE has got only one SGMII unit which is for port 6.
*/
- val = mt7530_read(priv, MT7531_TOP_SIG_SR);
+ regmap_read(priv->regmap, MT7531_TOP_SIG_SR, &val);
priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
/* Force link down on all ports before internal reset */
@@ -2880,7 +2879,7 @@ static void mt7531_rgmii_setup(struct mt7530_priv *priv,
{
u32 val;
- val = mt7530_read(priv, MT7531_CLKGEN_CTRL);
+ regmap_read(priv->regmap, MT7531_CLKGEN_CTRL, &val);
val |= GP_CLK_EN;
val &= ~GP_MODE_MASK;
val |= GP_MODE(MT7531_GP_MODE_RGMII);
@@ -3059,7 +3058,7 @@ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
config->lpi_capabilities = MAC_100FD | MAC_1000FD | MAC_2500FD;
- eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port));
+ regmap_read(priv->regmap, MT753X_PMEEECR_P(port), &eeecr);
/* tx_lpi_timer should be in microseconds. The time units for
* LPI threshold are unspecified.
*/
@@ -3087,7 +3086,7 @@ static void mt7530_pcs_get_state(struct phylink_pcs *pcs, unsigned int neg_mode,
int port = pcs_to_mt753x_pcs(pcs)->port;
u32 pmsr;
- pmsr = mt7530_read(priv, MT7530_PMSR_P(port));
+ regmap_read(priv->regmap, MT7530_PMSR_P(port), &pmsr);
state->link = (pmsr & PMSR_LINK);
state->an_complete = state->link;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v3 4/8] net: dsa: mt7530: replace mt7530_rmw/set/clear with regmap API
From: Daniel Golle @ 2026-06-15 5:21 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781500517.git.daniel@makrotopia.org>
Replace all mt7530_rmw() calls with regmap_update_bits(), mt7530_set()
with regmap_set_bits(), and mt7530_clear() with regmap_clear_bits().
Remove the wrapper function definitions.
Generated using the following semantic patch:
@@
expression priv, reg, mask, set;
@@
-mt7530_rmw(priv, reg, mask, set)
+regmap_update_bits(priv->regmap, reg, mask, set)
@@
expression priv, reg, val;
@@
-mt7530_set(priv, reg, val)
+regmap_set_bits(priv->regmap, reg, val)
@@
expression priv, reg, val;
@@
-mt7530_clear(priv, reg, val)
+regmap_clear_bits(priv->regmap, reg, val)
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: no changes
v2: remove stray 'static void' leftover
drivers/net/dsa/mt7530.c | 359 ++++++++++++++++++++-------------------
1 file changed, 182 insertions(+), 177 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index ce4efcf1b3e6..fe7e4ab5ae9c 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -174,25 +174,6 @@ mt7530_mii_poll(struct mt7530_dummy_poll *p)
return mt7530_read(p->priv, p->reg);
}
-static void
-mt7530_rmw(struct mt7530_priv *priv, u32 reg,
- u32 mask, u32 set)
-{
- regmap_update_bits(priv->regmap, reg, mask, set);
-}
-
-static void
-mt7530_set(struct mt7530_priv *priv, u32 reg, u32 val)
-{
- mt7530_rmw(priv, reg, val, val);
-}
-
-static void
-mt7530_clear(struct mt7530_priv *priv, u32 reg, u32 val)
-{
- mt7530_rmw(priv, reg, val, 0);
-}
-
static int
mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
{
@@ -332,12 +313,13 @@ mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
if (interface == PHY_INTERFACE_MODE_RGMII) {
- mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
- P6_INTF_MODE(0));
+ regmap_update_bits(priv->regmap, MT7530_P6ECR,
+ P6_INTF_MODE_MASK, P6_INTF_MODE(0));
return;
}
- mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
+ regmap_update_bits(priv->regmap, MT7530_P6ECR, P6_INTF_MODE_MASK,
+ P6_INTF_MODE(1));
xtal = mt7530_read(priv, MT753X_MTRAP) & MT7530_XTAL_MASK;
@@ -1258,35 +1240,35 @@ mt753x_trap_frames(struct mt7530_priv *priv)
* switch egress VLAN tag processing. This preserves VLAN tags
* for reception on VLAN sub-interfaces.
*/
- mt7530_rmw(priv, MT753X_BPC,
- PAE_BPDU_FR | PAE_EG_TAG_MASK | PAE_PORT_FW_MASK |
- BPDU_EG_TAG_MASK | BPDU_PORT_FW_MASK,
- PAE_BPDU_FR | PAE_EG_TAG(MT7530_VLAN_EG_DISABLED) |
- PAE_PORT_FW(TO_CPU_FW_CPU_ONLY) |
- BPDU_EG_TAG(MT7530_VLAN_EG_DISABLED) |
- TO_CPU_FW_CPU_ONLY);
+ regmap_update_bits(priv->regmap, MT753X_BPC,
+ PAE_BPDU_FR | PAE_EG_TAG_MASK | PAE_PORT_FW_MASK |
+ BPDU_EG_TAG_MASK | BPDU_PORT_FW_MASK,
+ PAE_BPDU_FR | PAE_EG_TAG(MT7530_VLAN_EG_DISABLED) |
+ PAE_PORT_FW(TO_CPU_FW_CPU_ONLY) |
+ BPDU_EG_TAG(MT7530_VLAN_EG_DISABLED) |
+ TO_CPU_FW_CPU_ONLY);
/* Trap frames with :01 and :02 MAC DAs to the CPU port(s) and
* egress them with EG_TAG disabled.
*/
- mt7530_rmw(priv, MT753X_RGAC1,
- R02_BPDU_FR | R02_EG_TAG_MASK | R02_PORT_FW_MASK |
- R01_BPDU_FR | R01_EG_TAG_MASK | R01_PORT_FW_MASK,
- R02_BPDU_FR | R02_EG_TAG(MT7530_VLAN_EG_DISABLED) |
- R02_PORT_FW(TO_CPU_FW_CPU_ONLY) | R01_BPDU_FR |
- R01_EG_TAG(MT7530_VLAN_EG_DISABLED) |
- TO_CPU_FW_CPU_ONLY);
+ regmap_update_bits(priv->regmap, MT753X_RGAC1,
+ R02_BPDU_FR | R02_EG_TAG_MASK | R02_PORT_FW_MASK |
+ R01_BPDU_FR | R01_EG_TAG_MASK | R01_PORT_FW_MASK,
+ R02_BPDU_FR | R02_EG_TAG(MT7530_VLAN_EG_DISABLED) |
+ R02_PORT_FW(TO_CPU_FW_CPU_ONLY) | R01_BPDU_FR |
+ R01_EG_TAG(MT7530_VLAN_EG_DISABLED) |
+ TO_CPU_FW_CPU_ONLY);
/* Trap frames with :03 and :0E MAC DAs to the CPU port(s) and
* egress them with EG_TAG disabled.
*/
- mt7530_rmw(priv, MT753X_RGAC2,
- R0E_BPDU_FR | R0E_EG_TAG_MASK | R0E_PORT_FW_MASK |
- R03_BPDU_FR | R03_EG_TAG_MASK | R03_PORT_FW_MASK,
- R0E_BPDU_FR | R0E_EG_TAG(MT7530_VLAN_EG_DISABLED) |
- R0E_PORT_FW(TO_CPU_FW_CPU_ONLY) | R03_BPDU_FR |
- R03_EG_TAG(MT7530_VLAN_EG_DISABLED) |
- TO_CPU_FW_CPU_ONLY);
+ regmap_update_bits(priv->regmap, MT753X_RGAC2,
+ R0E_BPDU_FR | R0E_EG_TAG_MASK | R0E_PORT_FW_MASK |
+ R03_BPDU_FR | R03_EG_TAG_MASK | R03_PORT_FW_MASK,
+ R0E_BPDU_FR | R0E_EG_TAG(MT7530_VLAN_EG_DISABLED) |
+ R0E_PORT_FW(TO_CPU_FW_CPU_ONLY) | R03_BPDU_FR |
+ R03_EG_TAG(MT7530_VLAN_EG_DISABLED) |
+ TO_CPU_FW_CPU_ONLY);
}
static void
@@ -1298,8 +1280,8 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
regmap_write(priv->regmap, MT7530_PVC_P(port), PORT_SPEC_TAG);
/* Enable flooding on the CPU port */
- mt7530_set(priv, MT753X_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) |
- UNU_FFP(BIT(port)));
+ regmap_set_bits(priv->regmap, MT753X_MFC,
+ BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) | UNU_FFP(BIT(port)));
/* Add the CPU port to the CPU port bitmap for MT7531 and the switch on
* the MT7988 SoC. Trapped frames will be forwarded to the CPU port that
@@ -1307,7 +1289,8 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
*/
if (priv->id == ID_MT7531 || priv->id == ID_MT7988 ||
priv->id == ID_EN7581 || priv->id == ID_AN7583)
- mt7530_set(priv, MT7531_CFC, MT7531_CPU_PMAP(BIT(port)));
+ regmap_set_bits(priv->regmap, MT7531_CFC,
+ MT7531_CPU_PMAP(BIT(port)));
/* CPU port gets connected to all user ports of
* the switch.
@@ -1316,8 +1299,8 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
PCR_MATRIX(dsa_user_ports(priv->ds)));
/* Set to fallback mode for independent VLAN learning */
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
- MT7530_PORT_FALLBACK_MODE);
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(port),
+ PCR_PORT_VLAN_MASK, MT7530_PORT_FALLBACK_MODE);
}
static int
@@ -1339,8 +1322,8 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
priv->ports[port].pm |= PCR_MATRIX(BIT(cpu_dp->index));
}
priv->ports[port].enable = true;
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
- priv->ports[port].pm);
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(port), PCR_MATRIX_MASK,
+ priv->ports[port].pm);
mutex_unlock(&priv->reg_mutex);
@@ -1348,9 +1331,9 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
return 0;
if (port == 5)
- mt7530_clear(priv, MT753X_MTRAP, MT7530_P5_DIS);
+ regmap_clear_bits(priv->regmap, MT753X_MTRAP, MT7530_P5_DIS);
else if (port == 6)
- mt7530_clear(priv, MT753X_MTRAP, MT7530_P6_DIS);
+ regmap_clear_bits(priv->regmap, MT753X_MTRAP, MT7530_P6_DIS);
return 0;
}
@@ -1366,8 +1349,8 @@ mt7530_port_disable(struct dsa_switch *ds, int port)
* enablement for the port.
*/
priv->ports[port].enable = false;
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
- PCR_MATRIX_CLR);
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(port), PCR_MATRIX_MASK,
+ PCR_MATRIX_CLR);
mutex_unlock(&priv->reg_mutex);
@@ -1376,9 +1359,9 @@ mt7530_port_disable(struct dsa_switch *ds, int port)
/* Do not set MT7530_P5_DIS when port 5 is being used for PHY muxing. */
if (port == 5 && priv->p5_mode == GMAC5)
- mt7530_set(priv, MT753X_MTRAP, MT7530_P5_DIS);
+ regmap_set_bits(priv->regmap, MT753X_MTRAP, MT7530_P5_DIS);
else if (port == 6)
- mt7530_set(priv, MT753X_MTRAP, MT7530_P6_DIS);
+ regmap_set_bits(priv->regmap, MT753X_MTRAP, MT7530_P6_DIS);
}
static int
@@ -1448,8 +1431,9 @@ mt7530_stp_state_set(struct dsa_switch *ds, int port, u8 state)
break;
}
- mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK(FID_BRIDGED),
- FID_PST(FID_BRIDGED, stp_state));
+ regmap_update_bits(priv->regmap, MT7530_SSP_P(port),
+ FID_PST_MASK(FID_BRIDGED),
+ FID_PST(FID_BRIDGED, stp_state));
}
static void mt7530_update_port_member(struct mt7530_priv *priv, int port,
@@ -1488,8 +1472,9 @@ static void mt7530_update_port_member(struct mt7530_priv *priv, int port,
}
if (other_p->enable)
- mt7530_rmw(priv, MT7530_PCR_P(other_port),
- PCR_MATRIX_MASK, other_p->pm);
+ regmap_update_bits(priv->regmap,
+ MT7530_PCR_P(other_port),
+ PCR_MATRIX_MASK, other_p->pm);
}
/* Add/remove the all other ports to this port matrix. For !join
@@ -1498,7 +1483,8 @@ static void mt7530_update_port_member(struct mt7530_priv *priv, int port,
*/
p->pm = PCR_MATRIX(port_bitmap);
if (priv->ports[port].enable)
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, p->pm);
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(port),
+ PCR_MATRIX_MASK, p->pm);
}
static int
@@ -1521,20 +1507,23 @@ mt7530_port_bridge_flags(struct dsa_switch *ds, int port,
struct mt7530_priv *priv = ds->priv;
if (flags.mask & BR_LEARNING)
- mt7530_rmw(priv, MT7530_PSC_P(port), SA_DIS,
- flags.val & BR_LEARNING ? 0 : SA_DIS);
+ regmap_update_bits(priv->regmap, MT7530_PSC_P(port), SA_DIS,
+ flags.val & BR_LEARNING ? 0 : SA_DIS);
if (flags.mask & BR_FLOOD)
- mt7530_rmw(priv, MT753X_MFC, UNU_FFP(BIT(port)),
- flags.val & BR_FLOOD ? UNU_FFP(BIT(port)) : 0);
+ regmap_update_bits(priv->regmap, MT753X_MFC,
+ UNU_FFP(BIT(port)),
+ flags.val & BR_FLOOD ? UNU_FFP(BIT(port)) : 0);
if (flags.mask & BR_MCAST_FLOOD)
- mt7530_rmw(priv, MT753X_MFC, UNM_FFP(BIT(port)),
- flags.val & BR_MCAST_FLOOD ? UNM_FFP(BIT(port)) : 0);
+ regmap_update_bits(priv->regmap, MT753X_MFC,
+ UNM_FFP(BIT(port)),
+ flags.val & BR_MCAST_FLOOD ? UNM_FFP(BIT(port)) : 0);
if (flags.mask & BR_BCAST_FLOOD)
- mt7530_rmw(priv, MT753X_MFC, BC_FFP(BIT(port)),
- flags.val & BR_BCAST_FLOOD ? BC_FFP(BIT(port)) : 0);
+ regmap_update_bits(priv->regmap, MT753X_MFC,
+ BC_FFP(BIT(port)),
+ flags.val & BR_BCAST_FLOOD ? BC_FFP(BIT(port)) : 0);
if (flags.mask & BR_ISOLATED) {
struct dsa_port *dp = dsa_to_port(ds, port);
@@ -1562,8 +1551,8 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
mt7530_update_port_member(priv, port, bridge.dev, true);
/* Set to fallback mode for independent VLAN learning */
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
- MT7530_PORT_FALLBACK_MODE);
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(port),
+ PCR_PORT_VLAN_MASK, MT7530_PORT_FALLBACK_MODE);
mutex_unlock(&priv->reg_mutex);
@@ -1624,18 +1613,19 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
* bridge. Don't set standalone ports to fallback mode.
*/
if (dsa_port_bridge_dev_get(dsa_to_port(ds, port)))
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
- MT7530_PORT_FALLBACK_MODE);
-
- mt7530_rmw(priv, MT7530_PVC_P(port),
- VLAN_ATTR_MASK | PVC_EG_TAG_MASK | ACC_FRM_MASK,
- VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
- PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT) |
- MT7530_VLAN_ACC_ALL);
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(port),
+ PCR_PORT_VLAN_MASK,
+ MT7530_PORT_FALLBACK_MODE);
+
+ regmap_update_bits(priv->regmap, MT7530_PVC_P(port),
+ VLAN_ATTR_MASK | PVC_EG_TAG_MASK | ACC_FRM_MASK,
+ VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
+ PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT) |
+ MT7530_VLAN_ACC_ALL);
/* Set PVID to 0 */
- mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
- G0_PORT_VID_DEF);
+ regmap_update_bits(priv->regmap, MT7530_PPBV1_P(port),
+ G0_PORT_VID_MASK, G0_PORT_VID_DEF);
for (i = 0; i < priv->ds->num_ports; i++) {
if (i == port)
@@ -1666,24 +1656,27 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port)
* table lookup.
*/
if (dsa_is_user_port(ds, port)) {
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
- MT7530_PORT_SECURITY_MODE);
- mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
- G0_PORT_VID(priv->ports[port].pvid));
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(port),
+ PCR_PORT_VLAN_MASK,
+ MT7530_PORT_SECURITY_MODE);
+ regmap_update_bits(priv->regmap, MT7530_PPBV1_P(port),
+ G0_PORT_VID_MASK,
+ G0_PORT_VID(priv->ports[port].pvid));
/* Only accept tagged frames if PVID is not set */
if (!priv->ports[port].pvid)
- mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
- MT7530_VLAN_ACC_TAGGED);
+ regmap_update_bits(priv->regmap, MT7530_PVC_P(port),
+ ACC_FRM_MASK,
+ MT7530_VLAN_ACC_TAGGED);
/* Set the port as a user port which is to be able to recognize
* VID from incoming packets before fetching entry within the
* VLAN table.
*/
- mt7530_rmw(priv, MT7530_PVC_P(port),
- VLAN_ATTR_MASK | PVC_EG_TAG_MASK,
- VLAN_ATTR(MT7530_VLAN_USER) |
- PVC_EG_TAG(MT7530_VLAN_EG_DISABLED));
+ regmap_update_bits(priv->regmap, MT7530_PVC_P(port),
+ VLAN_ATTR_MASK | PVC_EG_TAG_MASK,
+ VLAN_ATTR(MT7530_VLAN_USER) |
+ PVC_EG_TAG(MT7530_VLAN_EG_DISABLED));
} else {
/* Also set CPU ports to the "user" VLAN port attribute, to
* allow VLAN classification, but keep the EG_TAG attribute as
@@ -1692,8 +1685,9 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port)
* are forwarded to user ports as tagged, and untagged as
* untagged.
*/
- mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK,
- VLAN_ATTR(MT7530_VLAN_USER));
+ regmap_update_bits(priv->regmap, MT7530_PVC_P(port),
+ VLAN_ATTR_MASK,
+ VLAN_ATTR(MT7530_VLAN_USER));
}
}
@@ -1711,8 +1705,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
* back to the default as is at initial boot which is a VLAN-unaware
* port.
*/
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
- MT7530_PORT_MATRIX_MODE);
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(port),
+ PCR_PORT_VLAN_MASK, MT7530_PORT_MATRIX_MODE);
mutex_unlock(&priv->reg_mutex);
}
@@ -1893,9 +1887,9 @@ mt7530_hw_vlan_add(struct mt7530_priv *priv,
val = MT7530_VLAN_EGRESS_UNTAG;
else
val = MT7530_VLAN_EGRESS_TAG;
- mt7530_rmw(priv, MT7530_VAWD2,
- ETAG_CTRL_P_MASK(entry->port),
- ETAG_CTRL_P(entry->port, val));
+ regmap_update_bits(priv->regmap, MT7530_VAWD2,
+ ETAG_CTRL_P_MASK(entry->port),
+ ETAG_CTRL_P(entry->port, val));
}
static void
@@ -1973,25 +1967,26 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
priv->ports[port].pvid = vlan->vid;
/* Accept all frames if PVID is set */
- mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
- MT7530_VLAN_ACC_ALL);
+ regmap_update_bits(priv->regmap, MT7530_PVC_P(port),
+ ACC_FRM_MASK, MT7530_VLAN_ACC_ALL);
/* Only configure PVID if VLAN filtering is enabled */
if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
- mt7530_rmw(priv, MT7530_PPBV1_P(port),
- G0_PORT_VID_MASK,
- G0_PORT_VID(vlan->vid));
+ regmap_update_bits(priv->regmap, MT7530_PPBV1_P(port),
+ G0_PORT_VID_MASK,
+ G0_PORT_VID(vlan->vid));
} else if (vlan->vid && priv->ports[port].pvid == vlan->vid) {
/* This VLAN is overwritten without PVID, so unset it */
priv->ports[port].pvid = G0_PORT_VID_DEF;
/* Only accept tagged frames if the port is VLAN-aware */
if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
- mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
- MT7530_VLAN_ACC_TAGGED);
+ regmap_update_bits(priv->regmap, MT7530_PVC_P(port),
+ ACC_FRM_MASK,
+ MT7530_VLAN_ACC_TAGGED);
- mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
- G0_PORT_VID_DEF);
+ regmap_update_bits(priv->regmap, MT7530_PPBV1_P(port),
+ G0_PORT_VID_MASK, G0_PORT_VID_DEF);
}
mutex_unlock(&priv->reg_mutex);
@@ -2025,11 +2020,12 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
/* Only accept tagged frames if the port is VLAN-aware */
if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
- mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
- MT7530_VLAN_ACC_TAGGED);
+ regmap_update_bits(priv->regmap, MT7530_PVC_P(port),
+ ACC_FRM_MASK,
+ MT7530_VLAN_ACC_TAGGED);
- mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
- G0_PORT_VID_DEF);
+ regmap_update_bits(priv->regmap, MT7530_PPBV1_P(port),
+ G0_PORT_VID_MASK, G0_PORT_VID_DEF);
}
@@ -2136,9 +2132,9 @@ mt7530_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
u32 bit = mt7530_gpio_to_bit(offset);
if (value)
- mt7530_set(priv, MT7530_LED_GPIO_DATA, bit);
+ regmap_set_bits(priv->regmap, MT7530_LED_GPIO_DATA, bit);
else
- mt7530_clear(priv, MT7530_LED_GPIO_DATA, bit);
+ regmap_clear_bits(priv->regmap, MT7530_LED_GPIO_DATA, bit);
return 0;
}
@@ -2159,8 +2155,8 @@ mt7530_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
struct mt7530_priv *priv = gpiochip_get_data(gc);
u32 bit = mt7530_gpio_to_bit(offset);
- mt7530_clear(priv, MT7530_LED_GPIO_OE, bit);
- mt7530_clear(priv, MT7530_LED_GPIO_DIR, bit);
+ regmap_clear_bits(priv->regmap, MT7530_LED_GPIO_OE, bit);
+ regmap_clear_bits(priv->regmap, MT7530_LED_GPIO_DIR, bit);
return 0;
}
@@ -2171,14 +2167,14 @@ mt7530_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, int valu
struct mt7530_priv *priv = gpiochip_get_data(gc);
u32 bit = mt7530_gpio_to_bit(offset);
- mt7530_set(priv, MT7530_LED_GPIO_DIR, bit);
+ regmap_set_bits(priv->regmap, MT7530_LED_GPIO_DIR, bit);
if (value)
- mt7530_set(priv, MT7530_LED_GPIO_DATA, bit);
+ regmap_set_bits(priv->regmap, MT7530_LED_GPIO_DATA, bit);
else
- mt7530_clear(priv, MT7530_LED_GPIO_DATA, bit);
+ regmap_clear_bits(priv->regmap, MT7530_LED_GPIO_DATA, bit);
- mt7530_set(priv, MT7530_LED_GPIO_OE, bit);
+ regmap_set_bits(priv->regmap, MT7530_LED_GPIO_OE, bit);
return 0;
}
@@ -2284,7 +2280,8 @@ mt7530_setup_irq(struct mt7530_priv *priv)
/* This register must be set for MT7530 to properly fire interrupts */
if (priv->id == ID_MT7530 || priv->id == ID_MT7621)
- mt7530_set(priv, MT7530_TOP_SIG_CTRL, TOP_SIG_CTRL_NORMAL);
+ regmap_set_bits(priv->regmap, MT7530_TOP_SIG_CTRL,
+ TOP_SIG_CTRL_NORMAL);
ret = devm_regmap_add_irq_chip_fwnode(dev, dev_fwnode(dev),
priv->regmap, irq,
@@ -2462,14 +2459,15 @@ mt7530_setup(struct dsa_switch *ds)
TD_DM_DRVP(8) | TD_DM_DRVN(8));
for (i = 0; i < NUM_TRGMII_CTRL; i++)
- mt7530_rmw(priv, MT7530_TRGMII_RD(i),
- RD_TAP_MASK, RD_TAP(16));
+ regmap_update_bits(priv->regmap, MT7530_TRGMII_RD(i),
+ RD_TAP_MASK, RD_TAP(16));
/* Allow modifying the trap and directly access PHY registers via the
* MDIO bus the switch is on.
*/
- mt7530_rmw(priv, MT753X_MTRAP, MT7530_CHG_TRAP |
- MT7530_PHY_INDIRECT_ACCESS, MT7530_CHG_TRAP);
+ regmap_update_bits(priv->regmap, MT753X_MTRAP,
+ MT7530_CHG_TRAP | MT7530_PHY_INDIRECT_ACCESS,
+ MT7530_CHG_TRAP);
if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ)
mt7530_pll_setup(priv);
@@ -2483,17 +2481,16 @@ mt7530_setup(struct dsa_switch *ds)
/* Clear link settings and enable force mode to force link down
* on all ports until they're enabled later.
*/
- mt7530_rmw(priv, MT753X_PMCR_P(i),
- PMCR_LINK_SETTINGS_MASK |
- MT753X_FORCE_MODE(priv->id),
- MT753X_FORCE_MODE(priv->id));
+ regmap_update_bits(priv->regmap, MT753X_PMCR_P(i),
+ PMCR_LINK_SETTINGS_MASK | MT753X_FORCE_MODE(priv->id),
+ MT753X_FORCE_MODE(priv->id));
/* Disable forwarding by default on all ports */
- mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
- PCR_MATRIX_CLR);
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(i),
+ PCR_MATRIX_MASK, PCR_MATRIX_CLR);
/* Disable learning by default on all ports */
- mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+ regmap_set_bits(priv->regmap, MT7530_PSC_P(i), SA_DIS);
if (dsa_is_cpu_port(ds, i)) {
mt753x_cpu_port_enable(ds, i);
@@ -2501,16 +2498,17 @@ mt7530_setup(struct dsa_switch *ds)
mt7530_port_disable(ds, i);
/* Set default PVID to 0 on all user ports */
- mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
- G0_PORT_VID_DEF);
+ regmap_update_bits(priv->regmap, MT7530_PPBV1_P(i),
+ G0_PORT_VID_MASK, G0_PORT_VID_DEF);
}
/* Enable consistent egress tag */
- mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
- PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
+ regmap_update_bits(priv->regmap, MT7530_PVC_P(i),
+ PVC_EG_TAG_MASK,
+ PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
}
/* Allow mirroring frames received on the local port (monitor port). */
- mt7530_set(priv, MT753X_AGC, LOCAL_EN);
+ regmap_set_bits(priv->regmap, MT753X_AGC, LOCAL_EN);
/* Setup VLAN ID 0 for VLAN-unaware bridges */
ret = mt7530_setup_vlan0(priv);
@@ -2557,7 +2555,8 @@ mt7530_setup(struct dsa_switch *ds)
if (priv->p5_mode == MUX_PHY_P0 ||
priv->p5_mode == MUX_PHY_P4) {
- mt7530_clear(priv, MT753X_MTRAP, MT7530_P5_DIS);
+ regmap_clear_bits(priv->regmap, MT753X_MTRAP,
+ MT7530_P5_DIS);
mt7530_setup_port5(ds, interface);
}
}
@@ -2596,26 +2595,26 @@ mt7531_setup_common(struct dsa_switch *ds)
mt7530_mib_reset(ds);
/* Disable flooding on all ports */
- mt7530_clear(priv, MT753X_MFC, BC_FFP_MASK | UNM_FFP_MASK |
- UNU_FFP_MASK);
+ regmap_clear_bits(priv->regmap, MT753X_MFC,
+ BC_FFP_MASK | UNM_FFP_MASK | UNU_FFP_MASK);
for (i = 0; i < priv->ds->num_ports; i++) {
/* Clear link settings and enable force mode to force link down
* on all ports until they're enabled later.
*/
- mt7530_rmw(priv, MT753X_PMCR_P(i),
- PMCR_LINK_SETTINGS_MASK |
- MT753X_FORCE_MODE(priv->id),
- MT753X_FORCE_MODE(priv->id));
+ regmap_update_bits(priv->regmap, MT753X_PMCR_P(i),
+ PMCR_LINK_SETTINGS_MASK | MT753X_FORCE_MODE(priv->id),
+ MT753X_FORCE_MODE(priv->id));
/* Disable forwarding by default on all ports */
- mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
- PCR_MATRIX_CLR);
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(i),
+ PCR_MATRIX_MASK, PCR_MATRIX_CLR);
/* Disable learning by default on all ports */
- mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+ regmap_set_bits(priv->regmap, MT7530_PSC_P(i), SA_DIS);
- mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
+ regmap_set_bits(priv->regmap, MT7531_DBG_CNT(i),
+ MT7531_DIS_CLR);
if (dsa_is_cpu_port(ds, i)) {
mt753x_cpu_port_enable(ds, i);
@@ -2623,17 +2622,18 @@ mt7531_setup_common(struct dsa_switch *ds)
mt7530_port_disable(ds, i);
/* Set default PVID to 0 on all user ports */
- mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
- G0_PORT_VID_DEF);
+ regmap_update_bits(priv->regmap, MT7530_PPBV1_P(i),
+ G0_PORT_VID_MASK, G0_PORT_VID_DEF);
}
/* Enable consistent egress tag */
- mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
- PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
+ regmap_update_bits(priv->regmap, MT7530_PVC_P(i),
+ PVC_EG_TAG_MASK,
+ PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
}
/* Allow mirroring frames received on the local port (monitor port). */
- mt7530_set(priv, MT753X_AGC, LOCAL_EN);
+ regmap_set_bits(priv->regmap, MT753X_AGC, LOCAL_EN);
/* Enable Special Tag for rx frames */
if (priv->id == ID_EN7581 || priv->id == ID_AN7583)
@@ -2709,14 +2709,16 @@ mt7531_setup(struct dsa_switch *ds)
* MT7531AE. Set the GPIO 11-12 pins to function as MDC and MDIO
* to expose the MDIO bus of the switch.
*/
- mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO11_RG_RXD2_MASK,
- MT7531_EXT_P_MDC_11);
- mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO12_RG_RXD3_MASK,
- MT7531_EXT_P_MDIO_12);
+ regmap_update_bits(priv->regmap, MT7531_GPIO_MODE1,
+ MT7531_GPIO11_RG_RXD2_MASK,
+ MT7531_EXT_P_MDC_11);
+ regmap_update_bits(priv->regmap, MT7531_GPIO_MODE1,
+ MT7531_GPIO12_RG_RXD3_MASK,
+ MT7531_EXT_P_MDIO_12);
}
- mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
- MT7531_GPIO0_INTERRUPT);
+ regmap_update_bits(priv->regmap, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
+ MT7531_GPIO0_INTERRUPT);
/* Enable Energy-Efficient Ethernet (EEE) and PHY core PLL, since
* phy_device has not yet been created provided for
@@ -2962,7 +2964,8 @@ mt753x_phylink_mac_config(struct phylink_config *config, unsigned int mode,
/* Are we connected to external phy */
if (port == 5 && dsa_is_user_port(ds, 5))
- mt7530_set(priv, MT753X_PMCR_P(port), PMCR_EXT_PHY);
+ regmap_set_bits(priv->regmap, MT753X_PMCR_P(port),
+ PMCR_EXT_PHY);
}
static void mt753x_phylink_mac_link_down(struct phylink_config *config,
@@ -2972,7 +2975,8 @@ static void mt753x_phylink_mac_link_down(struct phylink_config *config,
struct dsa_port *dp = dsa_phylink_to_port(config);
struct mt7530_priv *priv = dp->ds->priv;
- mt7530_clear(priv, MT753X_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK);
+ regmap_clear_bits(priv->regmap, MT753X_PMCR_P(dp->index),
+ PMCR_LINK_SETTINGS_MASK);
}
static void mt753x_phylink_mac_link_up(struct phylink_config *config,
@@ -3006,7 +3010,7 @@ static void mt753x_phylink_mac_link_up(struct phylink_config *config,
mcr |= PMCR_FORCE_RX_FC_EN;
}
- mt7530_set(priv, MT753X_PMCR_P(dp->index), mcr);
+ regmap_set_bits(priv->regmap, MT753X_PMCR_P(dp->index), mcr);
}
static void mt753x_phylink_mac_disable_tx_lpi(struct phylink_config *config)
@@ -3014,8 +3018,8 @@ static void mt753x_phylink_mac_disable_tx_lpi(struct phylink_config *config)
struct dsa_port *dp = dsa_phylink_to_port(config);
struct mt7530_priv *priv = dp->ds->priv;
- mt7530_clear(priv, MT753X_PMCR_P(dp->index),
- PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100);
+ regmap_clear_bits(priv->regmap, MT753X_PMCR_P(dp->index),
+ PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100);
}
static int mt753x_phylink_mac_enable_tx_lpi(struct phylink_config *config,
@@ -3036,11 +3040,11 @@ static int mt753x_phylink_mac_enable_tx_lpi(struct phylink_config *config,
else
val = LPI_THRESH_MASK;
- mt7530_rmw(priv, MT753X_PMEEECR_P(dp->index),
- LPI_THRESH_MASK | LPI_MODE_EN, val);
+ regmap_update_bits(priv->regmap, MT753X_PMEEECR_P(dp->index),
+ LPI_THRESH_MASK | LPI_MODE_EN, val);
- mt7530_set(priv, MT753X_PMCR_P(dp->index),
- PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100);
+ regmap_set_bits(priv->regmap, MT753X_PMCR_P(dp->index),
+ PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100);
return 0;
}
@@ -3217,7 +3221,8 @@ mt753x_conduit_state_change(struct dsa_switch *ds,
MT7530_CPU_PORT(__ffs(priv->active_cpu_ports));
}
- mt7530_rmw(priv, MT753X_MFC, MT7530_CPU_EN | MT7530_CPU_PORT_MASK, val);
+ regmap_update_bits(priv->regmap, MT753X_MFC,
+ MT7530_CPU_EN | MT7530_CPU_PORT_MASK, val);
}
static int mt753x_tc_setup_qdisc_tbf(struct dsa_switch *ds, int port,
@@ -3234,8 +3239,8 @@ static int mt753x_tc_setup_qdisc_tbf(struct dsa_switch *ds, int port,
case TC_TBF_DESTROY: {
u32 val, tick;
- mt7530_rmw(priv, MT753X_GERLCR, EGR_BC_MASK,
- EGR_BC_CRC_IPG_PREAMBLE);
+ regmap_update_bits(priv->regmap, MT753X_GERLCR, EGR_BC_MASK,
+ EGR_BC_CRC_IPG_PREAMBLE);
/* if rate is greater than 10Mbps tick is 1/32 ms,
* 1ms otherwise
@@ -3279,13 +3284,13 @@ static int mt7988_setup(struct dsa_switch *ds)
/* AN7583 require additional tweak to CONN_CFG */
if (priv->id == ID_AN7583)
- mt7530_rmw(priv, AN7583_GEPHY_CONN_CFG,
- AN7583_CSR_DPHY_CKIN_SEL |
- AN7583_CSR_PHY_CORE_REG_CLK_SEL |
- AN7583_CSR_ETHER_AFE_PWD,
- AN7583_CSR_DPHY_CKIN_SEL |
- AN7583_CSR_PHY_CORE_REG_CLK_SEL |
- FIELD_PREP(AN7583_CSR_ETHER_AFE_PWD, 0));
+ regmap_update_bits(priv->regmap, AN7583_GEPHY_CONN_CFG,
+ AN7583_CSR_DPHY_CKIN_SEL |
+ AN7583_CSR_PHY_CORE_REG_CLK_SEL |
+ AN7583_CSR_ETHER_AFE_PWD,
+ AN7583_CSR_DPHY_CKIN_SEL |
+ AN7583_CSR_PHY_CORE_REG_CLK_SEL |
+ FIELD_PREP(AN7583_CSR_ETHER_AFE_PWD, 0));
/* Reset the switch PHYs */
regmap_write(priv->regmap, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST);
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v3 3/8] net: dsa: mt7530: replace mt7530_write with regmap_write
From: Daniel Golle @ 2026-06-15 5:21 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781500517.git.daniel@makrotopia.org>
Replace all mt7530_write() calls with direct regmap_write() calls
and remove the wrapper function. The per-call error logging is
dropped -- regmap has its own tracing infrastructure.
Generated using the following semantic patch:
@@
expression priv, reg, val;
@@
-mt7530_write(priv, reg, val)
+regmap_write(priv->regmap, reg, val)
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: no changes
v2: no changes
drivers/net/dsa/mt7530.c | 126 ++++++++++++++++++---------------------
1 file changed, 59 insertions(+), 67 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 9ccc848195cf..ce4efcf1b3e6 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -150,16 +150,6 @@ core_clear(struct mt7530_priv *priv, u32 reg, u32 val)
core_rmw(priv, reg, val, 0);
}
-static void
-mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
-{
- int ret;
-
- ret = regmap_write(priv->regmap, reg, val);
- if (ret < 0)
- dev_err(priv->dev,
- "failed to write mt7530 register\n");
-}
static u32
mt7530_read(struct mt7530_priv *priv, u32 reg)
@@ -212,7 +202,7 @@ mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
/* Set the command operating upon the MAC address entries */
val = ATC_BUSY | ATC_MAT(0) | cmd;
- mt7530_write(priv, MT7530_ATC, val);
+ regmap_write(priv->regmap, MT7530_ATC, val);
INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_ATC);
ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
@@ -288,7 +278,7 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
/* Write array into the ARL table */
for (i = 0; i < 3; i++)
- mt7530_write(priv, MT7530_ATA1 + (i * 4), reg[i]);
+ regmap_write(priv->regmap, MT7530_ATA1 + (i * 4), reg[i]);
}
/* Set up switch core clock for MT7530 */
@@ -406,27 +396,27 @@ mt7531_pll_setup(struct mt7530_priv *priv)
/* Step 1 : Disable MT7531 COREPLL */
val = mt7530_read(priv, MT7531_PLLGP_EN);
val &= ~EN_COREPLL;
- mt7530_write(priv, MT7531_PLLGP_EN, val);
+ regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
/* Step 2: switch to XTAL output */
val = mt7530_read(priv, MT7531_PLLGP_EN);
val |= SW_CLKSW;
- mt7530_write(priv, MT7531_PLLGP_EN, val);
+ regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
val = mt7530_read(priv, MT7531_PLLGP_CR0);
val &= ~RG_COREPLL_EN;
- mt7530_write(priv, MT7531_PLLGP_CR0, val);
+ regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
/* Step 3: disable PLLGP and enable program PLLGP */
val = mt7530_read(priv, MT7531_PLLGP_EN);
val |= SW_PLLGP;
- mt7530_write(priv, MT7531_PLLGP_EN, val);
+ regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
/* Step 4: program COREPLL output frequency to 500MHz */
val = mt7530_read(priv, MT7531_PLLGP_CR0);
val &= ~RG_COREPLL_POSDIV_M;
val |= 2 << RG_COREPLL_POSDIV_S;
- mt7530_write(priv, MT7531_PLLGP_CR0, val);
+ regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
usleep_range(25, 35);
switch (xtal) {
@@ -434,42 +424,42 @@ mt7531_pll_setup(struct mt7530_priv *priv)
val = mt7530_read(priv, MT7531_PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_M;
val |= 0x140000 << RG_COREPLL_SDM_PCW_S;
- mt7530_write(priv, MT7531_PLLGP_CR0, val);
+ regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
break;
case MT7531_XTAL_FSEL_40MHZ:
val = mt7530_read(priv, MT7531_PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_M;
val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
- mt7530_write(priv, MT7531_PLLGP_CR0, val);
+ regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
break;
}
/* Set feedback divide ratio update signal to high */
val = mt7530_read(priv, MT7531_PLLGP_CR0);
val |= RG_COREPLL_SDM_PCW_CHG;
- mt7530_write(priv, MT7531_PLLGP_CR0, val);
+ regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
/* Wait for at least 16 XTAL clocks */
usleep_range(10, 20);
/* Step 5: set feedback divide ratio update signal to low */
val = mt7530_read(priv, MT7531_PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_CHG;
- mt7530_write(priv, MT7531_PLLGP_CR0, val);
+ regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
/* Enable 325M clock for SGMII */
- mt7530_write(priv, MT7531_ANA_PLLGP_CR5, 0xad0000);
+ regmap_write(priv->regmap, MT7531_ANA_PLLGP_CR5, 0xad0000);
/* Enable 250SSC clock for RGMII */
- mt7530_write(priv, MT7531_ANA_PLLGP_CR2, 0x4f40000);
+ regmap_write(priv->regmap, MT7531_ANA_PLLGP_CR2, 0x4f40000);
/* Step 6: Enable MT7531 PLL */
val = mt7530_read(priv, MT7531_PLLGP_CR0);
val |= RG_COREPLL_EN;
- mt7530_write(priv, MT7531_PLLGP_CR0, val);
+ regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
val = mt7530_read(priv, MT7531_PLLGP_EN);
val |= EN_COREPLL;
- mt7530_write(priv, MT7531_PLLGP_EN, val);
+ regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
usleep_range(25, 35);
}
@@ -478,8 +468,8 @@ mt7530_mib_reset(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
- mt7530_write(priv, MT7530_MIB_CCR, CCR_MIB_FLUSH);
- mt7530_write(priv, MT7530_MIB_CCR, CCR_MIB_ACTIVATE);
+ regmap_write(priv->regmap, MT7530_MIB_CCR, CCR_MIB_FLUSH);
+ regmap_write(priv->regmap, MT7530_MIB_CCR, CCR_MIB_ACTIVATE);
}
static int mt7530_phy_read_c22(struct mt7530_priv *priv, int port, int regnum)
@@ -526,7 +516,7 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad) | regnum;
- mt7530_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ regmap_write(priv->regmap, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -537,7 +527,7 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_READ | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad);
- mt7530_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ regmap_write(priv->regmap, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -574,7 +564,7 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad) | regnum;
- mt7530_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ regmap_write(priv->regmap, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -585,7 +575,7 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_WRITE | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad) | data;
- mt7530_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ regmap_write(priv->regmap, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -621,7 +611,7 @@ mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
val = MT7531_MDIO_CL22_READ | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_REG_ADDR(regnum);
- mt7530_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
+ regmap_write(priv->regmap, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -659,7 +649,7 @@ mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
reg = MT7531_MDIO_CL22_WRITE | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_REG_ADDR(regnum) | data;
- mt7530_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ regmap_write(priv->regmap, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
ret = readx_poll_timeout(mt7530_mii_poll, &p, reg,
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
@@ -1012,7 +1002,8 @@ mt7530_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
}
}
- mt7530_write(priv, MT7530_AAC, AGE_CNT(age_count) | AGE_UNIT(age_unit));
+ regmap_write(priv->regmap, MT7530_AAC,
+ AGE_CNT(age_count) | AGE_UNIT(age_unit));
return 0;
}
@@ -1050,7 +1041,7 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
/* MUX_PHY_P4: P4 -> P5 -> SoC MAC */
case MUX_PHY_P4:
/* Setup the MAC by default for the cpu port */
- mt7530_write(priv, MT753X_PMCR_P(5), 0x56300);
+ regmap_write(priv->regmap, MT753X_PMCR_P(5), 0x56300);
break;
/* GMAC5: P5 -> SoC MAC or external PHY */
@@ -1064,7 +1055,8 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
val |= MT7530_P5_RGMII_MODE;
/* P5 RGMII RX Clock Control: delay setting for 1000M */
- mt7530_write(priv, MT7530_P5RGMIIRXCR, CSR_RGMII_EDGE_ALIGN);
+ regmap_write(priv->regmap, MT7530_P5RGMIIRXCR,
+ CSR_RGMII_EDGE_ALIGN);
/* Don't set delay in DSA mode */
if (!dsa_is_dsa_port(priv->ds, 5) &&
@@ -1073,15 +1065,15 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
tx_delay = 4; /* n * 0.5 ns */
/* P5 RGMII TX Clock Control: delay x */
- mt7530_write(priv, MT7530_P5RGMIITXCR,
+ regmap_write(priv->regmap, MT7530_P5RGMIITXCR,
CSR_RGMII_TXC_CFG(0x10 + tx_delay));
/* reduce P5 RGMII Tx driving, 8mA */
- mt7530_write(priv, MT7530_IO_DRV_CR,
+ regmap_write(priv->regmap, MT7530_IO_DRV_CR,
P5_IO_CLK_DRV(1) | P5_IO_DATA_DRV(1));
}
- mt7530_write(priv, MT753X_MTRAP, val);
+ regmap_write(priv->regmap, MT753X_MTRAP, val);
dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, mode=%s, phy-mode=%s\n", val,
mt7530_p5_mode_str(priv->p5_mode), phy_modes(interface));
@@ -1303,8 +1295,7 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
struct mt7530_priv *priv = ds->priv;
/* Enable Mediatek header mode on the cpu port */
- mt7530_write(priv, MT7530_PVC_P(port),
- PORT_SPEC_TAG);
+ regmap_write(priv->regmap, MT7530_PVC_P(port), PORT_SPEC_TAG);
/* Enable flooding on the CPU port */
mt7530_set(priv, MT753X_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) |
@@ -1321,7 +1312,7 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
/* CPU port gets connected to all user ports of
* the switch.
*/
- mt7530_write(priv, MT7530_PCR_P(port),
+ regmap_write(priv->regmap, MT7530_PCR_P(port),
PCR_MATRIX(dsa_user_ports(priv->ds)));
/* Set to fallback mode for independent VLAN learning */
@@ -1421,7 +1412,7 @@ mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
val |= MAX_RX_PKT_LEN_JUMBO;
}
- mt7530_write(priv, MT7530_GMACCR, val);
+ regmap_write(priv->regmap, MT7530_GMACCR, val);
return 0;
}
@@ -1587,7 +1578,7 @@ mt7530_vlan_cmd(struct mt7530_priv *priv, enum mt7530_vlan_cmd cmd, u16 vid)
int ret;
val = VTCR_BUSY | VTCR_FUNC(cmd) | vid;
- mt7530_write(priv, MT7530_VTCR, val);
+ regmap_write(priv->regmap, MT7530_VTCR, val);
INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_VTCR);
ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
@@ -1616,8 +1607,8 @@ mt7530_setup_vlan0(struct mt7530_priv *priv)
*/
val = IVL_MAC | EG_CON | PORT_MEM(MT7530_ALL_MEMBERS) | FID(FID_BRIDGED) |
VLAN_VALID;
- mt7530_write(priv, MT7530_VAWD1, val);
- mt7530_write(priv, MT7530_VAWD2, 0);
+ regmap_write(priv->regmap, MT7530_VAWD1, val);
+ regmap_write(priv->regmap, MT7530_VAWD2, 0);
return mt7530_vlan_cmd(priv, MT7530_VTCR_WR_VID, 0);
}
@@ -1887,7 +1878,7 @@ mt7530_hw_vlan_add(struct mt7530_priv *priv,
*/
val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | FID(FID_BRIDGED) |
VLAN_VALID;
- mt7530_write(priv, MT7530_VAWD1, val);
+ regmap_write(priv->regmap, MT7530_VAWD1, val);
/* Decide whether adding tag or not for those outgoing packets from the
* port inside the VLAN.
@@ -1926,10 +1917,10 @@ mt7530_hw_vlan_del(struct mt7530_priv *priv,
if (new_members) {
val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) |
VLAN_VALID;
- mt7530_write(priv, MT7530_VAWD1, val);
+ regmap_write(priv->regmap, MT7530_VAWD1, val);
} else {
- mt7530_write(priv, MT7530_VAWD1, 0);
- mt7530_write(priv, MT7530_VAWD2, 0);
+ regmap_write(priv->regmap, MT7530_VAWD1, 0);
+ regmap_write(priv->regmap, MT7530_VAWD2, 0);
}
}
@@ -2070,7 +2061,7 @@ static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
val |= MT753X_MIRROR_EN(priv->id);
val &= ~MT753X_MIRROR_PORT_MASK(priv->id);
val |= MT753X_MIRROR_PORT_SET(priv->id, mirror->to_local_port);
- mt7530_write(priv, MT753X_MIRROR_REG(priv->id), val);
+ regmap_write(priv->regmap, MT753X_MIRROR_REG(priv->id), val);
val = mt7530_read(priv, MT7530_PCR_P(port));
if (ingress) {
@@ -2080,7 +2071,7 @@ static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
val |= PORT_TX_MIR;
priv->mirror_tx |= BIT(port);
}
- mt7530_write(priv, MT7530_PCR_P(port), val);
+ regmap_write(priv->regmap, MT7530_PCR_P(port), val);
return 0;
}
@@ -2099,12 +2090,12 @@ static void mt753x_port_mirror_del(struct dsa_switch *ds, int port,
val &= ~PORT_TX_MIR;
priv->mirror_tx &= ~BIT(port);
}
- mt7530_write(priv, MT7530_PCR_P(port), val);
+ regmap_write(priv->regmap, MT7530_PCR_P(port), val);
if (!priv->mirror_rx && !priv->mirror_tx) {
val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id));
val &= ~MT753X_MIRROR_EN(priv->id);
- mt7530_write(priv, MT753X_MIRROR_REG(priv->id), val);
+ regmap_write(priv->regmap, MT753X_MIRROR_REG(priv->id), val);
}
}
@@ -2202,9 +2193,9 @@ mt7530_setup_gpio(struct mt7530_priv *priv)
if (!gc)
return -ENOMEM;
- mt7530_write(priv, MT7530_LED_GPIO_OE, 0);
- mt7530_write(priv, MT7530_LED_GPIO_DIR, 0);
- mt7530_write(priv, MT7530_LED_IO_MODE, 0);
+ regmap_write(priv->regmap, MT7530_LED_GPIO_OE, 0);
+ regmap_write(priv->regmap, MT7530_LED_GPIO_DIR, 0);
+ regmap_write(priv->regmap, MT7530_LED_IO_MODE, 0);
gc->label = "mt7530";
gc->parent = dev;
@@ -2462,13 +2453,12 @@ mt7530_setup(struct dsa_switch *ds)
}
/* Reset the switch through internal reset */
- mt7530_write(priv, MT7530_SYS_CTRL,
- SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
- SYS_CTRL_REG_RST);
+ regmap_write(priv->regmap, MT7530_SYS_CTRL,
+ SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST | SYS_CTRL_REG_RST);
/* Lower Tx driving for TRGMII path */
for (i = 0; i < NUM_TRGMII_CTRL; i++)
- mt7530_write(priv, MT7530_TRGMII_TD_ODT(i),
+ regmap_write(priv->regmap, MT7530_TRGMII_TD_ODT(i),
TD_DM_DRVP(8) | TD_DM_DRVN(8));
for (i = 0; i < NUM_TRGMII_CTRL; i++)
@@ -2647,7 +2637,7 @@ mt7531_setup_common(struct dsa_switch *ds)
/* Enable Special Tag for rx frames */
if (priv->id == ID_EN7581 || priv->id == ID_AN7583)
- mt7530_write(priv, MT753X_CPORT_SPTAG_CFG,
+ regmap_write(priv->regmap, MT753X_CPORT_SPTAG_CFG,
CPORT_SW2FE_STAG_EN | CPORT_FE2SW_STAG_EN);
/* Flush the FDB table */
@@ -2705,10 +2695,12 @@ mt7531_setup(struct dsa_switch *ds)
/* Force link down on all ports before internal reset */
for (i = 0; i < priv->ds->num_ports; i++)
- mt7530_write(priv, MT753X_PMCR_P(i), MT7531_FORCE_MODE_LNK);
+ regmap_write(priv->regmap, MT753X_PMCR_P(i),
+ MT7531_FORCE_MODE_LNK);
/* Reset the switch through internal reset */
- mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_SW_RST | SYS_CTRL_REG_RST);
+ regmap_write(priv->regmap, MT7530_SYS_CTRL,
+ SYS_CTRL_SW_RST | SYS_CTRL_REG_RST);
if (!priv->p5_sgmii) {
mt7531_pll_setup(priv);
@@ -2917,7 +2909,7 @@ static void mt7531_rgmii_setup(struct mt7530_priv *priv,
}
}
- mt7530_write(priv, MT7531_CLKGEN_CTRL, val);
+ regmap_write(priv->regmap, MT7531_CLKGEN_CTRL, val);
}
static void
@@ -3254,7 +3246,7 @@ static int mt753x_tc_setup_qdisc_tbf(struct dsa_switch *ds, int port,
FIELD_PREP(ERLCR_EXP_MASK, tick) |
ERLCR_TBF_MODE_MASK |
FIELD_PREP(ERLCR_MANT_MASK, 0xf);
- mt7530_write(priv, MT753X_ERLCR_P(port), val);
+ regmap_write(priv->regmap, MT753X_ERLCR_P(port), val);
break;
}
default:
@@ -3296,7 +3288,7 @@ static int mt7988_setup(struct dsa_switch *ds)
FIELD_PREP(AN7583_CSR_ETHER_AFE_PWD, 0));
/* Reset the switch PHYs */
- mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST);
+ regmap_write(priv->regmap, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST);
return mt7531_setup_common(ds);
}
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v3 2/8] net: dsa: mt7530: fold mt7530_mii_write/read into mt7530_write/read
From: Daniel Golle @ 2026-06-15 5:21 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781500517.git.daniel@makrotopia.org>
With the lock wrappers removed in the previous commit, mt7530_write()
was a trivial wrapper around mt7530_mii_write(), and mt7530_read()
around mt7530_mii_read() via _mt7530_read(). Fold the function bodies
and eliminate the intermediate functions.
The _mt7530_unlocked_read() and _mt7530_read() poll helpers, which
existed as locked/unlocked variants for readx_poll_timeout(), are
consolidated into a single mt7530_mii_poll() that calls mt7530_read().
Callers are updated using the following semantic patch:
@@
expression E1, E2, E3;
@@
-mt7530_mii_write(E1, E2, E3)
+mt7530_write(E1, E2, E3)
@@
expression E1, E2;
@@
-mt7530_mii_read(E1, E2)
+mt7530_read(E1, E2)
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v2: no changes
v3: no changes
drivers/net/dsa/mt7530.c | 78 ++++++++++++++--------------------------
1 file changed, 27 insertions(+), 51 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 5f56a423b147..9ccc848195cf 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -150,22 +150,19 @@ core_clear(struct mt7530_priv *priv, u32 reg, u32 val)
core_rmw(priv, reg, val, 0);
}
-static int
-mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
+static void
+mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
{
int ret;
ret = regmap_write(priv->regmap, reg, val);
-
if (ret < 0)
dev_err(priv->dev,
"failed to write mt7530 register\n");
-
- return ret;
}
static u32
-mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
+mt7530_read(struct mt7530_priv *priv, u32 reg)
{
int ret;
u32 val;
@@ -181,31 +178,10 @@ mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
return val;
}
-static void
-mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
-{
- mt7530_mii_write(priv, reg, val);
-}
-
static u32
-_mt7530_unlocked_read(struct mt7530_dummy_poll *p)
+mt7530_mii_poll(struct mt7530_dummy_poll *p)
{
- return mt7530_mii_read(p->priv, p->reg);
-}
-
-static u32
-_mt7530_read(struct mt7530_dummy_poll *p)
-{
- return mt7530_mii_read(p->priv, p->reg);
-}
-
-static u32
-mt7530_read(struct mt7530_priv *priv, u32 reg)
-{
- struct mt7530_dummy_poll p;
-
- INIT_MT7530_DUMMY_POLL(&p, priv, reg);
- return _mt7530_read(&p);
+ return mt7530_read(p->priv, p->reg);
}
static void
@@ -239,7 +215,7 @@ mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
mt7530_write(priv, MT7530_ATC, val);
INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_ATC);
- ret = readx_poll_timeout(_mt7530_read, &p, val,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & ATC_BUSY), 20, 20000);
if (ret < 0) {
dev_err(priv->dev, "reset timeout\n");
@@ -541,7 +517,7 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
mutex_lock(&priv->reg_mutex);
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
if (ret < 0) {
dev_err(priv->dev, "poll timeout\n");
@@ -550,9 +526,9 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad) | regnum;
- mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ mt7530_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
if (ret < 0) {
dev_err(priv->dev, "poll timeout\n");
@@ -561,9 +537,9 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_READ | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad);
- mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ mt7530_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
if (ret < 0) {
dev_err(priv->dev, "poll timeout\n");
@@ -589,7 +565,7 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
mutex_lock(&priv->reg_mutex);
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
if (ret < 0) {
dev_err(priv->dev, "poll timeout\n");
@@ -598,9 +574,9 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad) | regnum;
- mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ mt7530_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
if (ret < 0) {
dev_err(priv->dev, "poll timeout\n");
@@ -609,9 +585,9 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_WRITE | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad) | data;
- mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ mt7530_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
if (ret < 0) {
dev_err(priv->dev, "poll timeout\n");
@@ -635,7 +611,7 @@ mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
mutex_lock(&priv->reg_mutex);
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
if (ret < 0) {
dev_err(priv->dev, "poll timeout\n");
@@ -645,9 +621,9 @@ mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
val = MT7531_MDIO_CL22_READ | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_REG_ADDR(regnum);
- mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
+ mt7530_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
if (ret < 0) {
dev_err(priv->dev, "poll timeout\n");
@@ -673,7 +649,7 @@ mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
mutex_lock(&priv->reg_mutex);
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, reg,
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
if (ret < 0) {
dev_err(priv->dev, "poll timeout\n");
@@ -683,9 +659,9 @@ mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
reg = MT7531_MDIO_CL22_WRITE | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_REG_ADDR(regnum) | data;
- mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ mt7530_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
- ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, reg,
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
if (ret < 0) {
dev_err(priv->dev, "poll timeout\n");
@@ -1428,7 +1404,7 @@ mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
if (!dsa_is_cpu_port(ds, port))
return 0;
- val = mt7530_mii_read(priv, MT7530_GMACCR);
+ val = mt7530_read(priv, MT7530_GMACCR);
val &= ~MAX_RX_PKT_LEN_MASK;
/* RX length also includes Ethernet header, MTK tag, and FCS length */
@@ -1445,7 +1421,7 @@ mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
val |= MAX_RX_PKT_LEN_JUMBO;
}
- mt7530_mii_write(priv, MT7530_GMACCR, val);
+ mt7530_write(priv, MT7530_GMACCR, val);
return 0;
}
@@ -1614,7 +1590,7 @@ mt7530_vlan_cmd(struct mt7530_priv *priv, enum mt7530_vlan_cmd cmd, u16 vid)
mt7530_write(priv, MT7530_VTCR, val);
INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_VTCR);
- ret = readx_poll_timeout(_mt7530_read, &p, val,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val,
!(val & VTCR_BUSY), 20, 20000);
if (ret < 0) {
dev_err(priv->dev, "poll timeout\n");
@@ -2465,7 +2441,7 @@ mt7530_setup(struct dsa_switch *ds)
/* Waiting for MT7530 got to stable */
INIT_MT7530_DUMMY_POLL(&p, priv, MT753X_TRAP);
- ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val, val != 0,
20, 1000000);
if (ret < 0) {
dev_err(priv->dev, "reset timeout\n");
@@ -2706,7 +2682,7 @@ mt7531_setup(struct dsa_switch *ds)
/* Waiting for MT7530 got to stable */
INIT_MT7530_DUMMY_POLL(&p, priv, MT753X_TRAP);
- ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0,
+ ret = readx_poll_timeout(mt7530_mii_poll, &p, val, val != 0,
20, 1000000);
if (ret < 0) {
dev_err(priv->dev, "reset timeout\n");
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v3 1/8] net: dsa: mt7530: move MDIO bus locking into regmap
From: Daniel Golle @ 2026-06-15 5:21 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781500517.git.daniel@makrotopia.org>
The switch register regmap was created with .disable_locking = true,
relying on callers to manually lock the MDIO bus. Move the locking
into the regmap using .lock/.unlock callbacks, matching the PCS
regmaps that already do this. This allows any code path reaching the
regmap to be automatically protected.
With regmap handling bus locking, the manual mt7530_mutex_lock/unlock
wrappers in mt7530_write(), _mt7530_read(), mt7530_rmw() and
mt7530_port_change_mtu() become redundant and are removed.
The MT7531 indirect PHY access functions need serialization of their
multi-step register sequences, but no longer need to hold bus->mdio_lock
across the whole operation. Switch them to reg_mutex.
core_write()/core_rmw() are the only remaining callers of
mt7530_mutex_lock(). They access TRGMII core PHY registers via the
clause 22 MMD indirect protocol -- a separate register space that
bypasses regmap and needs manual bus->mdio_lock protection.
Generated using the following semantic patch:
// Remove mt7530_mutex_lock/unlock around single regmap-based calls.
@@
expression priv, reg, val;
@@
{
- mt7530_mutex_lock(priv);
-
mt7530_mii_write(priv, reg, val);
-
- mt7530_mutex_unlock(priv);
}
@@
expression priv, reg, mask, set;
@@
{
- mt7530_mutex_lock(priv);
-
regmap_update_bits(priv->regmap, reg, mask, set);
-
- mt7530_mutex_unlock(priv);
}
@@
expression p;
identifier val;
@@
{
- u32 val;
- mt7530_mutex_lock(p->priv);
- val = mt7530_mii_read(p->priv, p->reg);
- mt7530_mutex_unlock(p->priv);
- return val;
+ return mt7530_mii_read(p->priv, p->reg);
}
@@
expression priv;
@@
- mt7530_mutex_lock(priv);
val = mt7530_mii_read(priv, MT7530_GMACCR);
...
mt7530_mii_write(priv, MT7530_GMACCR, val);
- mt7530_mutex_unlock(priv);
@@
expression priv, port;
@@
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mt7530_mutex_lock(priv);
+ mutex_lock(&priv->reg_mutex);
@@
expression priv;
@@
out:
- mt7530_mutex_unlock(priv);
+ mutex_unlock(&priv->reg_mutex);
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v2: no changes
v3: no changes
drivers/net/dsa/mt7530-mdio.c | 9 ++++++---
drivers/net/dsa/mt7530.c | 38 +++++++++--------------------------
2 files changed, 15 insertions(+), 32 deletions(-)
diff --git a/drivers/net/dsa/mt7530-mdio.c b/drivers/net/dsa/mt7530-mdio.c
index 11ea924a9f35..f7c8eeb27211 100644
--- a/drivers/net/dsa/mt7530-mdio.c
+++ b/drivers/net/dsa/mt7530-mdio.c
@@ -141,12 +141,14 @@ static const struct regmap_config regmap_config = {
.val_bits = 32,
.reg_stride = 4,
.max_register = MT7530_CREV,
- .disable_locking = true,
+ .lock = mt7530_mdio_regmap_lock,
+ .unlock = mt7530_mdio_regmap_unlock,
};
static int
mt7530_probe(struct mdio_device *mdiodev)
{
+ struct regmap_config rc = regmap_config;
struct mt7530_priv *priv;
struct device_node *dn;
int ret;
@@ -200,8 +202,9 @@ mt7530_probe(struct mdio_device *mdiodev)
return PTR_ERR(priv->io_pwr);
}
- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
- ®map_config);
+ rc.lock_arg = &priv->bus->mdio_lock;
+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
+ priv, &rc);
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 3c2a3029b10c..5f56a423b147 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -184,11 +184,7 @@ mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
static void
mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
{
- mt7530_mutex_lock(priv);
-
mt7530_mii_write(priv, reg, val);
-
- mt7530_mutex_unlock(priv);
}
static u32
@@ -200,15 +196,7 @@ _mt7530_unlocked_read(struct mt7530_dummy_poll *p)
static u32
_mt7530_read(struct mt7530_dummy_poll *p)
{
- u32 val;
-
- mt7530_mutex_lock(p->priv);
-
- val = mt7530_mii_read(p->priv, p->reg);
-
- mt7530_mutex_unlock(p->priv);
-
- return val;
+ return mt7530_mii_read(p->priv, p->reg);
}
static u32
@@ -224,11 +212,7 @@ static void
mt7530_rmw(struct mt7530_priv *priv, u32 reg,
u32 mask, u32 set)
{
- mt7530_mutex_lock(priv);
-
regmap_update_bits(priv->regmap, reg, mask, set);
-
- mt7530_mutex_unlock(priv);
}
static void
@@ -555,7 +539,7 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mt7530_mutex_lock(priv);
+ mutex_lock(&priv->reg_mutex);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -588,7 +572,7 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
ret = val & MT7531_MDIO_RW_DATA_MASK;
out:
- mt7530_mutex_unlock(priv);
+ mutex_unlock(&priv->reg_mutex);
return ret;
}
@@ -603,7 +587,7 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mt7530_mutex_lock(priv);
+ mutex_lock(&priv->reg_mutex);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -635,7 +619,7 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
}
out:
- mt7530_mutex_unlock(priv);
+ mutex_unlock(&priv->reg_mutex);
return ret;
}
@@ -649,7 +633,7 @@ mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mt7530_mutex_lock(priv);
+ mutex_lock(&priv->reg_mutex);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -672,7 +656,7 @@ mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
ret = val & MT7531_MDIO_RW_DATA_MASK;
out:
- mt7530_mutex_unlock(priv);
+ mutex_unlock(&priv->reg_mutex);
return ret;
}
@@ -687,7 +671,7 @@ mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mt7530_mutex_lock(priv);
+ mutex_lock(&priv->reg_mutex);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
@@ -709,7 +693,7 @@ mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
}
out:
- mt7530_mutex_unlock(priv);
+ mutex_unlock(&priv->reg_mutex);
return ret;
}
@@ -1444,8 +1428,6 @@ mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
if (!dsa_is_cpu_port(ds, port))
return 0;
- mt7530_mutex_lock(priv);
-
val = mt7530_mii_read(priv, MT7530_GMACCR);
val &= ~MAX_RX_PKT_LEN_MASK;
@@ -1465,8 +1447,6 @@ mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
mt7530_mii_write(priv, MT7530_GMACCR, val);
- mt7530_mutex_unlock(priv);
-
return 0;
}
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v3 0/8] net: dsa: mt7530: modernise register access and add two DSA ops
From: Daniel Golle @ 2026-06-15 5:20 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
The mt7530 driver carries its own register accessors that predate the
regmap conversion and now largely duplicate what regmap already
provides, including locking. Most of this series removes that layer.
It first moves the MDIO bus locking into the switch regmap via
.lock/.unlock callbacks, matching the PCS regmaps, so any path reaching
the regmap is serialised automatically. With the wrappers no longer
adding locking, the thin mt7530_mii_* indirection is folded away and the
remaining accessors are replaced mechanically with the plain regmap API,
using the coccinelle semantic patches included in the commit messages.
Open-coded register fields are then converted to FIELD_GET/FIELD_PREP.
None of this is intended to change behaviour.
The last two patches implement .port_fast_age, which flushes dynamically
learned MAC entries on topology changes, and .port_change_conduit, which
moves a user port's CPU-port affinity at runtime.
---
v3:
* 5/8: initialise register read-back variables to 0 so a failed
regmap_read keeps the previous read-as-zero behaviour, and use u32
for the value in mt7530_setup_port5
* 6/8: name the age timer field AGE_TIMER_MASK and document the
corrected ATC_HASH/VTCR_VID field macros
* 7/8: serialise the port_fast_age ATC flush under reg_mutex and log
on timeout, align a define, and correct the commit message which
wrongly claimed per-port parity with b53/realtek
* 8/8: populate the netlink extack on rejection and refuse a conduit
that lives on a different switch
v2:
* fix stray 'static void' left-over in 4/8 which had a fix accidentally
folded into 5/8 (byte-identical state at 8/8, but bisectability is
restored)
* extend port_change_conduit op commit message
Daniel Golle (8):
net: dsa: mt7530: move MDIO bus locking into regmap
net: dsa: mt7530: fold mt7530_mii_write/read into mt7530_write/read
net: dsa: mt7530: replace mt7530_write with regmap_write
net: dsa: mt7530: replace mt7530_rmw/set/clear with regmap API
net: dsa: mt7530: replace mt7530_read with regmap_read
net: dsa: mt7530: convert to use field accessor macros
net: dsa: mt7530: implement port_fast_age
net: dsa: mt7530: implement port_change_conduit op
drivers/net/dsa/mt7530-mdio.c | 9 +-
drivers/net/dsa/mt7530.c | 823 +++++++++++++++++-----------------
drivers/net/dsa/mt7530.h | 209 +++++----
3 files changed, 541 insertions(+), 500 deletions(-)
base-commit: 2319688890d97c63da423a3c57c23b4ab5952dfc
--
2.54.0
^ permalink raw reply
* Re: [PATCH v2 7/8] dt-bindings: display: allwinner: Split H616 DE33 layer reg space
From: Krzysztof Kozlowski @ 2026-06-15 4:28 UTC (permalink / raw)
To: Jernej Škrabec, wens
Cc: samuel, mripard, maarten.lankhorst, tzimmermann, airlied, simona,
robh, krzk+dt, conor+dt, mturquette, sboyd, dri-devel, devicetree,
linux-arm-kernel, linux-sunxi, linux-kernel, linux-clk
In-Reply-To: <nIKN_benRn2Bk8SDZrkMCA@gmail.com>
On 14/06/2026 16:08, Jernej Škrabec wrote:
> Dne ponedeljek, 25. maj 2026 ob 14:10:38 Srednjeevropski poletni čas je Krzysztof Kozlowski napisal(a):
>> On 24/05/2026 23:33, Chen-Yu Tsai wrote:
>>> Hi,
>>>
>>> (resent from new email)
>>>
>>> On Thu, May 14, 2026 at 2:04 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>>>
>>>> On Sat, May 09, 2026 at 09:00:14PM +0200, Jernej Skrabec wrote:
>>>>> From: Jernej Skrabec <jernej.skrabec@gmail.com>
>>>>>
>>>>> As it turns out, current H616 DE33 binding was written based on
>>>>> incomplete understanding of DE33 design. Namely, planes are shared
>>>>> resource and not tied to specific mixer, which was the case for previous
>>>>> generations of Display Engine (DE3 and earlier).
>>>>>
>>>>> This means that current DE33 binding doesn't properly reflect HW and
>>>>> using it would mean that second mixer (used for second display output)
>>>>> can't be supported.
>>>>>
>>>>> Remove layer register space, which will be represented with additional
>>>>> node, and replace it with phandle, which will point to that new, shared
>>>>> node. That way, all mixers can share same layers.
>>>>>
>>>>> There is no user of this binding yet, so changes can be made safely,
>>>>> without breaking any backward compatibility.
>>>>
>>>> There is user. git grep gives me:
>>>> drivers/gpu/drm/sun4i/sun8i_mixer.c
>>>>
>>>> which means this is a released ABI. As I understood, the old code was
>>>
>>> We held off on merging the DT changes so that we could rework this.
>>> I can't find the actual request though. It was probably over IRC.
>>>
>>>> working fine but just did not support all use cases. Why this cannot be
>>>> kept backwards compatible?
>>>
>>> AFAIK the "planes" block is shared between two display mixers. As the
>>> commit message explains, this prevents using the second mixer, since
>>> only one of them can claim and map the register space. And on the H700
>>> (which is the same die as the H616 discussed here but with more exposed
>>> interfaces), there could actually be a use case for the second mixer.
>>
>> It explains why you want to make the changes but not why you cannot keep
>> it backwards compatible.
>
> I guess it can be backward compatible, but I don't think it makes sense.
> Yes, original driver implemented original DT bindings, but there is no node
> which uses that binding. If there is no user of that, why would driver
Did you check all out of tree users of the ABI? All vendor kernels,
forks and all of them for which the ABI was made for?
If there is no single downstream/out of tree kernel using this ABI, then
of course you do not need to consider it. I don't know how would you
prove that but I am open for suggestions.
> need to support it nevertheless? Supporting only actually used DT binding
> allows for better code architecture, as there is no need to support second,
> unused path. It also simplifies testing, since developer doesn't need to
> test both paths if code is changed in that area.
>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH RFC 6/9] arm64: dts: qcom: shikra: Add ethernet nodes
From: Mohd Ayaan Anwar @ 2026-06-15 4:26 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Richard Cochran, Bjorn Andersson, Konrad Dybcio, Maxime Coquelin,
Alexandre Torgue, Russell King
Cc: linux-arm-msm, netdev, devicetree, linux-kernel, linux-stm32,
linux-arm-kernel
In-Reply-To: <20260612-shikra_ethernet-v1-6-f0f4a1d19929@oss.qualcomm.com>
On Fri, Jun 12, 2026 at 12:07:02AM +0530, Mohd Ayaan Anwar wrote:
> + clocks = <&gcc GCC_EMAC0_AXI_CLK>,
> + <&gcc GCC_EMAC0_AHB_CLK>,
> + <&gcc GCC_EMAC0_PTP_CLK>,
> + <&gcc GCC_EMAC0_RGMII_CLK>,
> + <&gcc GCC_EMAC0_AXI_CLK>,
> + <&gcc GCC_EMAC0_AXI_SYS_NOC_CLK>,
> + <&gcc GCC_PCIE_TILE_AXI_SYS_NOC_CLK>;
> + clock-names = "stmmaceth", "pclk", "ptp_ref", "rgmii",
> + "axi", "axi-noc", "pcie-tile-axi-noc";
> +
I now realize that having GCC_EMAC0_AXI_CLK for both "stmmaceth" and
"axi" clocks is probably wrong. I will remove "axi" and have the glue
driver enable and set rates for "stmmaceth", "axi-noc" and
"pcie-tile-axi-noc" to ungate DDR access.
Ayaan
^ permalink raw reply
* [PATCH 0/6] Some random fixes and cleanups to irqchip/gic-v3-its
From: Kemeng Shi @ 2026-06-15 3:29 UTC (permalink / raw)
To: maz, tglx; +Cc: linux-arm-kernel, linux-kernel, shikemeng
There are some random fixes and cleanups to irqchip/gic-v3-its. More
details can be found in respective patches.
Thanks.
Kemeng Shi (6):
irqchip/gic-v3-its: Fix LPI range leak and refactor error handler in
its_lpi_alloc()
irqchip/gic-v3-its: Fix memleak in its_probe_one()
irqchip/gic-v3-its: Fix its node leak in gic_acpi_parse_madt_its()
irqchip/gic-v3-its: Add ITS address info in more error logs
irqchip/gic-v3-its: fix typo in comments
irqchip/gic-v3-its: some minor cleanups
drivers/irqchip/irq-gic-v3-its.c | 68 ++++++++++++++++++--------------
1 file changed, 39 insertions(+), 29 deletions(-)
--
2.36.1
^ permalink raw reply
* Re: [PATCH RFC 0/2] pinctrl: Add support gpiod_to_irq
From: Xianwei Zhao @ 2026-06-15 3:17 UTC (permalink / raw)
To: Linus Walleij
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Neil Armstrong,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl, linux-amlogic,
linux-gpio, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <CAD++jLk3YdMUSkk71rgT=taQZnEhqgMgGP0dKBPx7_5Bsxmu+g@mail.gmail.com>
Hi Linus,
Thank you for your advice and review.
On 2026/6/11 20:51, Linus Walleij wrote:
> Hi Xianwei,
>
> thanks for your patches!
>
> On Thu, Jun 11, 2026 at 9:54 AM Xianwei Zhao via B4 Relay
> <devnull+xianwei.zhao.amlogic.com@kernel.org> wrote:
>
>> Some users need to obtain an IRQ directly from a GPIO descriptor through gpiod_to_irq().
>> Add the required DT binding and implementation to support this use case.
>> Since this introduces a new DT property, the property is kept optional to
>> maintain compatibility with existing SoCs and DTS files.
> To me it looks like you have just re-implemented hierarchical
> irqs.
>
> Look into the section "Infrastructure helpers for GPIO irqchips"
> in Documentation/driver-api/gpio/driver.rst, especially towards
> the end.
>
> Solve this by using GPIOLIB_IRQCHIP and a custom
> child_to_parent_hwirq() callback to translate the GPIO into
> an IRQ.
>
> To just implement gpiod_to_irq() without any irqchip abstraction
> is also broken: you can't force all users to just use this way
> to get an IRQ it's excessively restricting.
>
> Add
>
> interrupt-controller: true
>
> "#interrupt-cells":
> const: 2
>
> to the pinctrl node as well so that DT users can simply request
> the IRQ from the irqchip inside of the pin controller. It will
> be hierarchical and lightweight but an irqchip nevertheless.
>
> The GPIOLIB_IRQCHIP approach will help you to get this
> right.
>
I read the document (Documentation/driver-api/gpio/driver.rst) you
pointed me to and found that the corresponding implementation has
already been added in this file:
https://github.com/torvalds/linux/blob/master/drivers/irqchip/irq-meson-gpio.c
However, it is implemented as a standalone irqchip and is not integrated
with the GPIO controller.
In this patch, I implemented the GPIO-to-IRQ conversion through
gpiod_to_irq(). Users can still obtain the interrupt directly through
the interrupt property, for example:
interrupts-extended = <&gpio_intc 16 1>;
The purpose of this change is to make GPIO-to-IRQ conversion easier for
users who do not want to know the actual interrupt number. The interrupt
mapping is not fixed and varies between different SoCs, so users should
not need to handle the hardware interrupt allocation details.
> Yours,
> Linus Walleij
^ permalink raw reply
* Re: [PATCH RFC 7/9] arm64: dts: qcom: shikra-cqm-evk: Enable ethernet0
From: Mohd Ayaan Anwar @ 2026-06-15 3:55 UTC (permalink / raw)
To: Andrew Lunn
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Richard Cochran, Bjorn Andersson, Konrad Dybcio, Maxime Coquelin,
Alexandre Torgue, Russell King, linux-arm-msm, netdev, devicetree,
linux-kernel, linux-stm32, linux-arm-kernel
In-Reply-To: <6fde35ce-52dd-4679-9952-728b6553b843@lunn.ch>
On Thu, Jun 11, 2026 at 10:58:39PM +0200, Andrew Lunn wrote:
> > + ethphy0: ethernet-phy@7 {
> > + compatible = "ethernet-phy-ieee802.3-c22";
> > + reg = <7>;
> > + reset-gpios = <&tlmm 135 GPIO_ACTIVE_LOW>;
> > + reset-assert-us = <10000>;
> > + reset-deassert-us = <50000>;
> > + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
> > + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
>
> Are these two needed? It should default to 2ns, since that is what the
> RGMII standard says the delay should be.
>
That is true, I will remove these in v2.
Ayaan
^ permalink raw reply
* Re: [PATCH RFC 3/9] net: stmmac: qcom-ethqos: fix RGMII_ID mode to use DLL bypass
From: Mohd Ayaan Anwar @ 2026-06-15 3:54 UTC (permalink / raw)
To: Andrew Lunn
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Richard Cochran, Bjorn Andersson, Konrad Dybcio, Maxime Coquelin,
Alexandre Torgue, Russell King, linux-arm-msm, netdev, devicetree,
linux-kernel, linux-stm32, linux-arm-kernel
In-Reply-To: <42355330-c22a-4fce-98ab-dc22b321ff16@lunn.ch>
Hello Andrew,
On Thu, Jun 11, 2026 at 10:54:37PM +0200, Andrew Lunn wrote:
> On Fri, Jun 12, 2026 at 12:06:59AM +0530, Mohd Ayaan Anwar wrote:
> > When "rgmii-id" is selected the PHY supplies both TX and RX delays, so
> > the MAC must not add its own. The driver currently falls through to the
> > generic DLL initialisation path which programs it to add a delay.
> >
> > Power down the DLL and set DDR bypass mode for RGMII_ID, then program
> > the IO_MACRO via a new ethqos_rgmii_id_macro_init() helper. Also fix
> > ethqos_set_clk_tx_rate() to not double the clock rate in bypass mode at
> > 100M/10M, and remove RGMII_ID from the phase-shift suppression in
> > ethqos_rgmii_macro_init() since RGMII_ID no longer reaches that path.
>
> I'm curious how this works at the moment? Do no boards make use of
> RGMII ID? Are all current boards broken?
Searching through the DTS, I found that we have two boards using "rgmii"
(qcs404-evb-4000.dts and sa8155-adp.dts) and another board using
"rgmii-txid" (sa8540p-ride.dts). No board which uses RGMII ID.
I don't think any of these boards have extra long wires which would add
PCB level delay. They are against the netdev definitions for "rgmii" and
"rgmii-txid".
But the first two boards should still be working fine since the current
driver programs the IO_MACRO to add the delay when operating in RGMII
mode. I am not sure about the last board. I went through the different
versions of the ETHQOS programming guide, and it should reliably support
either only MAC side Rx/Tx delay -or- bypass mode (no MAC side delay),
with each having different clock requirements.
Ayaan
^ permalink raw reply
* [PATCH 8/8] clk: clocking-wizard: Use dev_err_probe() when mapping registers
From: Shubhrajyoti Datta @ 2026-06-15 3:48 UTC (permalink / raw)
To: linux-clk, linux-kernel
Cc: git, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Michal Simek,
Shubhrajyoti Datta, devicetree, linux-arm-kernel
In-Reply-To: <20260615034845.3320286-1-shubhrajyoti.datta@amd.com>
Align the devm_platform_ioremap_resource() error path with clk_in1 and
s_axi_aclk handling for consistent logging and deferred-probe behavior.
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
---
drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index fe73ee02b54e..381e396aef0e 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -1277,7 +1277,8 @@ static int clk_wzrd_probe(struct platform_device *pdev)
clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(clk_wzrd->base))
- return PTR_ERR(clk_wzrd->base);
+ return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->base),
+ "failed to map registers\n");
ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade);
if (!ret) {
--
2.49.1
^ permalink raw reply related
* [PATCH 7/8] clk: clocking-wizard: Skip s_axi_aclk for static-config
From: Shubhrajyoti Datta @ 2026-06-15 3:48 UTC (permalink / raw)
To: linux-clk, linux-kernel
Cc: git, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Michal Simek,
Shubhrajyoti Datta, devicetree, linux-arm-kernel
In-Reply-To: <20260615034845.3320286-1-shubhrajyoti.datta@amd.com>
For static-config mode the AXI bus interface is not used, so there is
no need to get and enable s_axi_aclk. Move the axi_clk setup inside
the non-static-config branch.
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
---
drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 23 +++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index 5470a717fccc..fe73ee02b54e 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -1243,7 +1243,6 @@ static int clk_wzrd_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct clk_wzrd *clk_wzrd;
const char *clk_name;
- unsigned long rate;
struct clk_hw *hw;
int nr_outputs;
int ret, i;
@@ -1258,22 +1257,24 @@ static int clk_wzrd_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, clk_wzrd);
- clk_wzrd->axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk");
- if (IS_ERR(clk_wzrd->axi_clk))
- return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk),
- "s_axi_aclk not found\n");
- rate = clk_get_rate(clk_wzrd->axi_clk);
- if (rate > WZRD_ACLK_MAX_FREQ) {
- dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n", rate);
- return -EINVAL;
- }
-
clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1");
if (IS_ERR(clk_wzrd->clk_in1))
return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1),
"failed to get clk_in1\n");
if (!of_property_present(np, "xlnx,static-config")) {
+ unsigned long rate;
+
+ clk_wzrd->axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk");
+ if (IS_ERR(clk_wzrd->axi_clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk),
+ "s_axi_aclk not found\n");
+ rate = clk_get_rate(clk_wzrd->axi_clk);
+ if (rate > WZRD_ACLK_MAX_FREQ) {
+ dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n", rate);
+ return -EINVAL;
+ }
+
clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(clk_wzrd->base))
return PTR_ERR(clk_wzrd->base);
--
2.49.1
^ permalink raw reply related
* [PATCH 6/8] clk: clocking-wizard: Add static-config clock provider support
From: Shubhrajyoti Datta @ 2026-06-15 3:48 UTC (permalink / raw)
To: linux-clk, linux-kernel
Cc: git, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Michal Simek,
Shubhrajyoti Datta, devicetree, linux-arm-kernel
In-Reply-To: <20260615034845.3320286-1-shubhrajyoti.datta@amd.com>
When xlnx,static-config is present the divider/multiplier path is
synthesized inside the Wizard without exposing runtime MMIO
reconfiguration, so omit the AXI register mapping and advertise each
routed output clock as a clk_fixed_factor child of clk_in1 using the
synthesized ratios exported through xlnx,clk-mul-div.
However the parent clock of clk_in1 can still be gated, disabled, or
(re-)enabled after FPGA programming (typical FPGA Manager flows,
CCF-managed parents, PLL fabric power sequencing).
Add a 10 us delay in each output clock's .enable() hook so consumers
wait for reference settling before first access.
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
---
drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 137 ++++++++++++++++++++-
1 file changed, 136 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index ffc78c90bee6..5470a717fccc 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
+#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/of.h>
@@ -107,6 +108,7 @@
#define VER_WZRD_O_MAX 511
#define WZRD_MIN_ERR 20000
#define WZRD_FRAC_POINTS 1000
+#define WZRD_ENABLE_DELAY_US 10
/* Get the mask from width */
#define div_mask(width) ((1 << (width)) - 1)
@@ -697,6 +699,13 @@ static int clk_wzrd_ver_determine_rate_all(struct clk_hw *hw,
return 0;
}
+static int clk_wzrd_enable(struct clk_hw *hw)
+{
+ /* Allow the output clock to settle after enable */
+ udelay(WZRD_ENABLE_DELAY_US);
+ return 0;
+}
+
static const struct clk_ops clk_wzrd_ver_divider_ops = {
.determine_rate = clk_wzrd_determine_rate,
.set_rate = clk_wzrd_ver_dynamic_reconfig,
@@ -790,6 +799,85 @@ static const struct clk_ops clk_wzrd_clk_divider_ops_f = {
.recalc_rate = clk_wzrd_recalc_ratef,
};
+static unsigned long
+clk_wzrd_static_factor_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
+ unsigned long long rate;
+
+ rate = (unsigned long long)parent_rate * fix->mult;
+ do_div(rate, fix->div);
+ return (unsigned long)rate;
+}
+
+static int clk_wzrd_static_factor_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
+
+ if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
+ unsigned long best_parent;
+
+ best_parent = (req->rate / fix->mult) * fix->div;
+ req->best_parent_rate =
+ clk_hw_round_rate(clk_hw_get_parent(hw), best_parent);
+ }
+
+ req->rate = (req->best_parent_rate / fix->div) * fix->mult;
+
+ return 0;
+}
+
+static int clk_wzrd_static_factor_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+ return 0;
+}
+
+static const struct clk_ops clk_wzrd_static_fixed_factor_ops = {
+ .enable = clk_wzrd_enable,
+ .determine_rate = clk_wzrd_static_factor_determine_rate,
+ .set_rate = clk_wzrd_static_factor_set_rate,
+ .recalc_rate = clk_wzrd_static_factor_recalc_rate,
+};
+
+static struct clk_hw *
+clk_wzrd_devm_register_static_fixed_factor(struct device *dev,
+ const char *name,
+ const struct clk_parent_data *parent_data,
+ unsigned long flags,
+ unsigned int mult,
+ unsigned int div)
+{
+ struct clk_init_data init = {};
+ struct clk_fixed_factor *fix;
+ struct clk_hw *hw;
+ int ret;
+
+ fix = devm_kzalloc(dev, sizeof(*fix), GFP_KERNEL);
+ if (!fix)
+ return ERR_PTR(-ENOMEM);
+
+ fix->mult = mult;
+ fix->div = div;
+
+ init.name = name;
+ init.ops = &clk_wzrd_static_fixed_factor_ops;
+ init.flags = flags;
+ init.parent_data = parent_data;
+ init.num_parents = 1;
+
+ fix->hw.init = &init;
+
+ hw = &fix->hw;
+ ret = devm_clk_hw_register(dev, hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return hw;
+}
+
static struct clk_hw *clk_wzrd_register_divf(struct device *dev,
const char *name,
const char *parent_name,
@@ -1154,9 +1242,11 @@ static int clk_wzrd_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct clk_wzrd *clk_wzrd;
+ const char *clk_name;
unsigned long rate;
+ struct clk_hw *hw;
int nr_outputs;
- int ret;
+ int ret, i;
ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs);
if (ret || nr_outputs > WZRD_NUM_OUTPUTS)
@@ -1224,6 +1314,51 @@ static int clk_wzrd_probe(struct platform_device *pdev)
dev_warn(&pdev->dev,
"unable to register clock notifier\n");
}
+ } else {
+ u32 mul_div[WZRD_NUM_OUTPUTS * 2];
+ const struct clk_parent_data parent_data = { .fw_name = "clk_in1" };
+ int num_elems = nr_outputs * 2;
+
+ /*
+ * xlnx,clk-mul-div is a uint32-matrix of <mul div> pairs;
+ * FDT encodes it as a flat u32 array so we can read it directly.
+ */
+ ret = of_property_read_u32_array(np, "xlnx,clk-mul-div",
+ mul_div, num_elems);
+ if (ret) {
+ dev_err(&pdev->dev, "xlnx,clk-mul-div missing or invalid\n");
+ return ret;
+ }
+
+ for (i = 0; i < nr_outputs; i++) {
+ u32 mul = mul_div[2 * i];
+ u32 div = mul_div[2 * i + 1];
+
+ if (!mul || !div)
+ return dev_err_probe(&pdev->dev, -EINVAL,
+ "invalid mul/div for clkout%d\n", i);
+
+ clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+ "%s_out%d", dev_name(&pdev->dev), i);
+ if (!clk_name)
+ return -ENOMEM;
+
+ hw = clk_wzrd_devm_register_static_fixed_factor(&pdev->dev, clk_name,
+ &parent_data,
+ CLK_SET_RATE_PARENT,
+ mul, div);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+ clk_wzrd->clk_data.hws[i] = hw;
+ }
+
+ clk_wzrd->clk_data.num = nr_outputs;
+
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get,
+ &clk_wzrd->clk_data);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "unable to register clock provider\n");
}
return 0;
--
2.49.1
^ permalink raw reply related
* [PATCH 4/8] clk: clocking-wizard: Do not map the memory for static-config
From: Shubhrajyoti Datta @ 2026-06-15 3:48 UTC (permalink / raw)
To: linux-clk, linux-kernel
Cc: git, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Michal Simek,
Shubhrajyoti Datta, devicetree, linux-arm-kernel
In-Reply-To: <20260615034845.3320286-1-shubhrajyoti.datta@amd.com>
With xlnx,static-config the MMCM/PLL topology is fixed at synthesis time
and no register programming is performed; only the dynamic path needs
the AXI register block. Move devm_platform_ioremap_resource() under the
non-static-config branch.
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
---
drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index 4a0136349f71..e082051221be 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -1168,10 +1168,6 @@ static int clk_wzrd_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, clk_wzrd);
- clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(clk_wzrd->base))
- return PTR_ERR(clk_wzrd->base);
-
clk_wzrd->axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk");
if (IS_ERR(clk_wzrd->axi_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk),
@@ -1183,6 +1179,10 @@ static int clk_wzrd_probe(struct platform_device *pdev)
}
if (!of_property_present(np, "xlnx,static-config")) {
+ clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(clk_wzrd->base))
+ return PTR_ERR(clk_wzrd->base);
+
ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade);
if (!ret) {
if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) {
--
2.49.1
^ permalink raw reply related
* [PATCH 5/8] clk: clocking-wizard: Move clk_in1 acquisition before static-config check
From: Shubhrajyoti Datta @ 2026-06-15 3:48 UTC (permalink / raw)
To: linux-clk, linux-kernel
Cc: git, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Michal Simek,
Shubhrajyoti Datta, devicetree, linux-arm-kernel
In-Reply-To: <20260615034845.3320286-1-shubhrajyoti.datta@amd.com>
The clk_in1 is the input clock for both the dynamic reconfig and the
static-config paths. Acquire clk_in1 for static-config as well. Output
clocks are registered as fixed-factor children of clk_in1.
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
---
drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index e082051221be..ffc78c90bee6 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -1178,6 +1178,11 @@ static int clk_wzrd_probe(struct platform_device *pdev)
return -EINVAL;
}
+ clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1");
+ if (IS_ERR(clk_wzrd->clk_in1))
+ return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1),
+ "failed to get clk_in1\n");
+
if (!of_property_present(np, "xlnx,static-config")) {
clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(clk_wzrd->base))
@@ -1192,11 +1197,6 @@ static int clk_wzrd_probe(struct platform_device *pdev)
}
}
- clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1");
- if (IS_ERR(clk_wzrd->clk_in1))
- return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1),
- "clk_in1 not found\n");
-
ret = clk_wzrd_register_output_clocks(&pdev->dev, nr_outputs);
if (ret)
return ret;
--
2.49.1
^ permalink raw reply related
* [PATCH 3/8] dt-bindings: clock: clocking-wizard: Make s_axi_aclk optional for static-config
From: Shubhrajyoti Datta @ 2026-06-15 3:48 UTC (permalink / raw)
To: linux-clk, linux-kernel
Cc: git, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Michal Simek,
Shubhrajyoti Datta, devicetree, linux-arm-kernel
In-Reply-To: <20260615034845.3320286-1-shubhrajyoti.datta@amd.com>
In static-config mode the AXI bus interface is unused, so s_axi_aclk
is not required. Allow clocks/clock-names to have only one entry
(clk_in1) when xlnx,static-config is present and enforce two entries
otherwise. Update the static-config example accordingly.
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
---
.../bindings/clock/xlnx,clocking-wizard.yaml | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
index aa397550d107..0daefe89ea89 100644
--- a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
+++ b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
@@ -29,11 +29,13 @@ properties:
const: 1
clocks:
+ minItems: 1
items:
- description: clock input
- description: axi clock
clock-names:
+ minItems: 1
items:
- const: clk_in1
- const: s_axi_aclk
@@ -87,9 +89,19 @@ allOf:
then:
required:
- xlnx,clk-mul-div
+ properties:
+ clocks:
+ maxItems: 1
+ clock-names:
+ maxItems: 1
else:
required:
- reg
+ properties:
+ clocks:
+ minItems: 2
+ clock-names:
+ minItems: 2
additionalProperties: false
@@ -109,8 +121,8 @@ examples:
clock-controller {
compatible = "xlnx,clocking-wizard";
#clock-cells = <1>;
- clocks = <&clkc 15>, <&clkc 18>;
- clock-names = "clk_in1", "s_axi_aclk";
+ clocks = <&clkc 15>;
+ clock-names = "clk_in1";
xlnx,nr-outputs = <6>;
xlnx,speed-grade = <1>;
xlnx,static-config;
--
2.49.1
^ permalink raw reply related
* [PATCH 0/8] clk: clocking-wizard: Add static-config clock provider support
From: Shubhrajyoti Datta @ 2026-06-15 3:48 UTC (permalink / raw)
To: linux-clk, linux-kernel
Cc: git, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Michal Simek,
Shubhrajyoti Datta, devicetree, linux-arm-kernel
The Xilinx clocking-wizard IP can be used in a static-config mode
where the hardware is pre-programmed at boot and no dynamic register
access is required. In that case the driver should skip ioremap,
read the fixed multiplier/divisor pairs from the device tree, and
register fixed-factor clocks derived from clk_in1.
Currently the xlnx,static-config is not functional as it doesnot
model the output clocks. The series fixes the same.
This series:
- adds the xlnx,clk-mul-div binding to carry mul/div pairs
- makes the reg property optional for static-config nodes
- skips ioremap when xlnx,static-config is present
- moves clk_in1 acquisition before the static-config check so it
is available in both code paths
- registers fixed-factor output clocks in static-config mode
Shubhrajyoti Datta (8):
dt-bindings: clock: clocking-wizard: Add xlnx,clk-mul-div property
dt-bindings: clock: clocking-wizard: Make reg optional for
static-config
dt-bindings: clock: clocking-wizard: Make s_axi_aclk optional for
static-config
clk: clocking-wizard: Do not map the memory for static-config
clk: clocking-wizard: Move clk_in1 acquisition before static-config
check
clk: clocking-wizard: Add static-config clock provider support
clk: clocking-wizard: Skip s_axi_aclk for static-config
clk: clocking-wizard: Use dev_err_probe() when mapping registers
.../bindings/clock/xlnx,clocking-wizard.yaml | 50 ++++-
drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 181 ++++++++++++++++--
2 files changed, 205 insertions(+), 26 deletions(-)
--
2.34.1
^ 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