* [PATCH net-next 5/8] net: dsa: mt7530: replace mt7530_read with regmap_read
From: Daniel Golle @ 2026-06-10 19:56 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.1781119435.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>
---
drivers/net/dsa/mt7530.c | 115 +++++++++++++++++++--------------------
1 file changed, 56 insertions(+), 59 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 0b561621fbdf..4168adca949f 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -152,30 +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;
- 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 void
-
static int
mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
{
@@ -198,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;
@@ -216,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]);
@@ -323,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;
@@ -367,9 +354,9 @@ mt7531_pll_setup(struct mt7530_priv *priv)
u32 hwstrap;
u32 val;
- 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;
@@ -378,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);
@@ -405,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);
@@ -419,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);
@@ -437,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);
@@ -700,11 +687,11 @@ mt7530_read_port_stats(struct mt7530_priv *priv, int port,
{
u32 val, 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;
}
}
@@ -1012,7 +999,7 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
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;
@@ -1380,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 */
@@ -1579,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;
@@ -1791,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);
@@ -1818,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,
@@ -1903,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");
@@ -1930,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;
@@ -2048,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);
@@ -2061,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);
@@ -2080,7 +2071,7 @@ static void mt753x_port_mirror_del(struct dsa_switch *ds, int port,
struct mt7530_priv *priv = ds->priv;
u32 val;
- 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);
@@ -2091,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);
}
@@ -2123,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;
+
+ regmap_read(priv->regmap, MT7530_LED_GPIO_DATA, &val);
- return !!(mt7530_read(priv, MT7530_LED_GPIO_DATA) & bit);
+ return !!(val & bit);
}
static int
@@ -2146,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;
}
@@ -2438,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);
@@ -2681,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) {
@@ -2692,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 */
@@ -2882,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);
@@ -3061,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.
*/
@@ -3089,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 4/8] net: dsa: mt7530: replace mt7530_rmw/set/clear with regmap API
From: Daniel Golle @ 2026-06-10 19:55 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.1781119435.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>
---
drivers/net/dsa/mt7530.c | 357 ++++++++++++++++++++-------------------
1 file changed, 182 insertions(+), 175 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index ce4efcf1b3e6..0b561621fbdf 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -175,23 +175,6 @@ mt7530_mii_poll(struct mt7530_dummy_poll *p)
}
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 +315,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 +1242,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 +1282,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 +1291,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 +1301,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 +1324,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 +1333,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 +1351,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 +1361,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 +1433,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 +1474,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 +1485,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 +1509,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 +1553,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 +1615,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 +1658,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 +1687,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 +1707,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 +1889,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 +1969,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 +2022,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 +2134,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 +2157,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 +2169,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 +2282,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 +2461,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 +2483,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 +2500,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 +2557,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 +2597,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 +2624,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 +2711,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 +2966,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 +2977,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 +3012,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 +3020,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 +3042,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 +3223,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 +3241,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 +3286,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 3/8] net: dsa: mt7530: replace mt7530_write with regmap_write
From: Daniel Golle @ 2026-06-10 19:55 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.1781119435.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>
---
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 2/8] net: dsa: mt7530: fold mt7530_mii_write/read into mt7530_write/read
From: Daniel Golle @ 2026-06-10 19:55 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.1781119435.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>
---
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 1/8] net: dsa: mt7530: move MDIO bus locking into regmap
From: Daniel Golle @ 2026-06-10 19:55 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.1781119435.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>
---
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 0/8] net: dsa: mt7530: modernise register access and add two DSA ops
From: Daniel Golle @ 2026-06-10 19:55 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.
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 | 791 +++++++++++++++++-----------------
drivers/net/dsa/mt7530.h | 209 +++++----
3 files changed, 517 insertions(+), 492 deletions(-)
--
2.54.0
^ permalink raw reply
* Re: (subset) [PATCH v2 00/15] var-som-6ul: improve support for variants
From: Frank.Li @ 2026-06-10 19:18 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, andrzej.hajda, neil.armstrong, rfoss,
Laurent.pinchart, jonas, jernej.skrabec, maarten.lankhorst,
mripard, tzimmermann, airlied, simona, s.hauer, kernel, festevam,
shawnguo, laurent.pinchart+renesas, antonin.godard,
Hugo Villeneuve
Cc: Frank Li, devicetree, linux-kernel, dri-devel, imx,
linux-arm-kernel, Hugo Villeneuve
In-Reply-To: <20260305180651.1827087-1-hugo@hugovil.com>
From: Frank Li <Frank.Li@nxp.com>
On Thu, 05 Mar 2026 13:06:15 -0500, Hugo Villeneuve wrote:
> From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
>
> Hello,
> this patch series improves support for Variscite VAR-SOM-6UL based boards.
>
> The first two patches fix DT/dmesg warnings.
>
> [...]
Applied, thanks!
[14/15] dt-bindings: display/lvds-codec: add ti,sn65lvds93
commit: bd584193a91ef2e190a2cf19f9320387fda1a21d
Other dts part already picked by me. This binding have not picked by
subsystem mainatiner by twice ping. I picked it to avoid CHECK_DTB warnings.
Best regards,
--
Frank Li <Frank.Li@nxp.com>
^ permalink raw reply
* Re: (subset) [PATCH v4 0/3] Reserve eDMA channels 0-1 for V2X
From: Frank.Li @ 2026-06-10 19:08 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Peng Fan,
Ye Li, Joy Zou
Cc: Frank Li, devicetree, imx, linux-arm-kernel, linux-kernel,
Laurentiu Mihalcea
In-Reply-To: <20260211-b4-imx95-v2x-v4-0-10852754b267@nxp.com>
From: Frank Li <Frank.Li@nxp.com>
On Wed, 11 Feb 2026 17:28:23 +0800, Joy Zou wrote:
Applied, thanks!
[1/3] dt-bindings: dma: fsl-edma: add dma-channel-mask property description
commit: edc448e785891cca747e21c6595e050d3d3fa434
Vnod have not picked it for the long time. I picked it to make reflect the
correct settings for i.mx
Best regards,
--
Frank Li <Frank.Li@nxp.com>
^ permalink raw reply
* Re: [PATCH net-next v3 0/3] Add standard stats for HSR/PRP
From: Simon Horman @ 2026-06-10 18:47 UTC (permalink / raw)
To: MD Danish Anwar
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Jonathan Corbet, Shuah Khan, Roger Quadros, Andrew Lunn,
Jacob Keller, Meghana Malladi, David Carlier, Vadim Fedorenko,
Kevin Hao, Himanshu Mittal, Hangbin Liu, Markus Elfring,
Fernando Fernandez Mancera, Jan Vaclav, netdev, linux-doc,
linux-kernel, linux-arm-kernel, Felix Maurer, Luka Gejak
In-Reply-To: <20260608100930.210149-1-danishanwar@ti.com>
On Mon, Jun 08, 2026 at 03:39:27PM +0530, MD Danish Anwar wrote:
> Add standard stats for HSR / PRP. This series was initially adding HSR/PRP
> related stats for ICSSG driver. Based on maintainers' comments on v2 I am
> now adding support to dump standard stats for HSR/PRP.
>
> The drivers which support offload can populate these standard stats.
>
> This series only implements offloaded stats. For software-only interfaces
> Felix Maurer had said he will do it later [1]
>
> v2 https://lore.kernel.org/all/20260514075605.850674-1-danishanwar@ti.com/
> [1] https://lore.kernel.org/all/ag87pBZfOyccPZTc@thinkpad/
>
> Cc: Jakub Kicinski <kuba@kernel.org>
> Cc: Felix Maurer <fmaurer@redhat.com>
> Cc: Luka Gejak <luka.gejak@linux.dev>
Hi MD,
There is AI-generated review of this patch-set available on both
https://sashiko.dev and https://netdev-ai.bots.linux.dev/sashiko/
I would appreciate it if you could look over that with a view
to addressing any issues that directly affect this patch-set.
^ permalink raw reply
* [PATCH 2/2] clocksource/drivers/arm_arch_timer_mmio: Restore support for early init
From: Stephan Gerhold @ 2026-06-10 17:53 UTC (permalink / raw)
To: Mark Rutland, Marc Zyngier, Daniel Lezcano, Thomas Gleixner,
Sudeep Holla
Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Jack Matthews
In-Reply-To: <20260610-arm-arch-timer-mmio-early-v1-0-ac17218ec8b4@linaro.org>
Some single-core Qualcomm modem platforms (e.g. MDM9625, MDM9607) have an
obscure timer setup where the global Arm MMIO timer (arm,armv7-timer-mem)
is used as the only available timer for the CPU. This setup used to work
fine until commit 0f67b56d84b4 ("clocksource/drivers/arm_arch_timer_mmio:
Switch over to standalone driver") when the early timer initialization
using TIMER_OF_DECLARE() was removed when moving to the standalone MMIO
driver.
We need some timer early to run properly, so without another timer in the
system the only choice is to make the MMIO timer available early again
using TIMER_OF_DECLARE(). Use the refactoring in the previous commit to
reuse most of the initialization code in the new standalone driver and
probe one timer early if required. ACPI-based systems and platforms with a
CPU-local CP15 timer continue to probe the timer late as before.
Reported-by: Jack Matthews <jack@jackmatthe.ws>
Closes: https://lore.kernel.org/r/46A20F89-E208-4091-8B6E-B5C38BF82B42@jackmatthe.ws/
Fixes: 0f67b56d84b4 ("clocksource/drivers/arm_arch_timer_mmio: Switch over to standalone driver")
Signed-off-by: Stephan Gerhold <stephan.gerhold@linaro.org>
---
I couldn't find any existing (fully-supported) platform upstream that
relies on this, so I omitted Cc stable. MDM9607 does have most of the
necessary drivers upstream, it's just missing the DT (I would like to
upstream that once ready).
---
drivers/clocksource/arm_arch_timer_mmio.c | 47 +++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/drivers/clocksource/arm_arch_timer_mmio.c b/drivers/clocksource/arm_arch_timer_mmio.c
index 5cb94051c4be..d128dff7067f 100644
--- a/drivers/clocksource/arm_arch_timer_mmio.c
+++ b/drivers/clocksource/arm_arch_timer_mmio.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
@@ -409,6 +410,8 @@ static struct arch_timer *arch_timer_mmio_init(struct arch_timer_mem *gt_block,
return_ptr(at);
}
+static struct device_node *arch_timer_mmio_early_np;
+
static int arch_timer_mmio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -417,6 +420,10 @@ static int arch_timer_mmio_probe(struct platform_device *pdev)
int ret;
if (np) {
+ /* Check if timer was already probed early */
+ if (np == arch_timer_mmio_early_np)
+ return 0;
+
gt_block = devm_kzalloc(&pdev->dev, sizeof(*gt_block),
GFP_KERNEL);
if (!gt_block)
@@ -436,6 +443,46 @@ static int arch_timer_mmio_probe(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id arch_timer_cp15_match[] __initconst = {
+ { .compatible = "arm,armv7-timer", },
+ { .compatible = "arm,armv8-timer", },
+ {}
+};
+
+static bool __init arch_timer_mmio_has_cp15(void)
+{
+ struct device_node *np __free(device_node) =
+ of_find_matching_node(NULL, arch_timer_cp15_match);
+
+ return np && of_device_is_available(np);
+}
+
+static int __init arch_timer_mmio_of_early_init(struct device_node *np)
+{
+ struct arch_timer *at;
+ int ret;
+
+ if (arch_timer_mmio_early_np || arch_timer_mmio_has_cp15())
+ return -EPROBE_DEFER;
+
+ struct arch_timer_mem *gt_block __free(kfree) = kzalloc_obj(*gt_block);
+ if (!gt_block)
+ return -ENOMEM;
+
+ ret = of_populate_gt_block(np, gt_block);
+ if (ret)
+ return ret;
+
+ at = arch_timer_mmio_init(gt_block, np);
+ if (IS_ERR(at))
+ return PTR_ERR(at);
+ retain_and_null_ptr(gt_block);
+
+ arch_timer_mmio_early_np = np;
+ return 0;
+}
+TIMER_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", arch_timer_mmio_of_early_init);
+
static const struct of_device_id arch_timer_mmio_of_table[] = {
{ .compatible = "arm,armv7-timer-mem", },
{}
--
2.54.0
^ permalink raw reply related
* [PATCH 1/2] clocksource/drivers/arm_arch_timer_mmio: Refactor for early init
From: Stephan Gerhold @ 2026-06-10 17:53 UTC (permalink / raw)
To: Mark Rutland, Marc Zyngier, Daniel Lezcano, Thomas Gleixner,
Sudeep Holla
Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Jack Matthews
In-Reply-To: <20260610-arm-arch-timer-mmio-early-v1-0-ac17218ec8b4@linaro.org>
In preparation of restoring support for using arm,armv7-timer-mem as an
early timer, refactor the driver to allow early initialization without
a device pointer. Replace uses of dev_() logging with pr_(), replace devm
helpers with manual cleanup or scope-based cleanup helpers where possible.
Create a new arch_timer_mmio_init() function that performs the
initialization and registration without a device pointer.
This is not very pretty, although given that the driver cannot be removed
at runtime due to .suppress_bind_attrs = true, at least the overhead for
the manual resource management is limited.
Signed-off-by: Stephan Gerhold <stephan.gerhold@linaro.org>
---
drivers/clocksource/arm_arch_timer_mmio.c | 139 +++++++++++++++++-------------
1 file changed, 79 insertions(+), 60 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer_mmio.c b/drivers/clocksource/arm_arch_timer_mmio.c
index d10362692fdd..5cb94051c4be 100644
--- a/drivers/clocksource/arm_arch_timer_mmio.c
+++ b/drivers/clocksource/arm_arch_timer_mmio.c
@@ -10,7 +10,9 @@
#define pr_fmt(fmt) "arch_timer_mmio: " fmt
+#include <linux/cleanup.h>
#include <linux/clockchips.h>
+#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/of_irq.h>
@@ -191,17 +193,16 @@ static irqreturn_t arch_timer_mmio_handler(int irq, void *dev_id)
return IRQ_NONE;
}
-static struct arch_timer_mem_frame *find_best_frame(struct platform_device *pdev)
+static struct arch_timer_mem_frame *find_best_frame(struct arch_timer *at)
{
struct arch_timer_mem_frame *frame, *best_frame = NULL;
- struct arch_timer *at = platform_get_drvdata(pdev);
void __iomem *cntctlbase;
u32 cnttidr;
cntctlbase = ioremap(at->gt_block->cntctlbase, at->gt_block->size);
if (!cntctlbase) {
- dev_err(&pdev->dev, "Can't map CNTCTLBase @ %pa\n",
- &at->gt_block->cntctlbase);
+ pr_err("Can't map CNTCTLBase @ %pa\n",
+ &at->gt_block->cntctlbase);
return NULL;
}
@@ -277,22 +278,21 @@ static void arch_timer_mmio_setup(struct arch_timer *at, int irq)
clocksource_register_hz(&at->cs, at->rate);
}
-static int arch_timer_mmio_frame_register(struct platform_device *pdev,
- struct arch_timer_mem_frame *frame)
+static int arch_timer_mmio_frame_register(struct arch_timer *at,
+ struct arch_timer_mem_frame *frame,
+ struct device_node *np)
{
- struct arch_timer *at = platform_get_drvdata(pdev);
- struct device_node *np = pdev->dev.of_node;
int ret, irq;
u32 rate;
- if (!devm_request_mem_region(&pdev->dev, frame->cntbase, frame->size,
- "arch_mem_timer"))
+ if (!request_mem_region(frame->cntbase, frame->size, "arch_mem_timer"))
return -EBUSY;
- at->base = devm_ioremap(&pdev->dev, frame->cntbase, frame->size);
+ at->base = ioremap(frame->cntbase, frame->size);
if (!at->base) {
- dev_err(&pdev->dev, "Can't map frame's registers\n");
- return -ENXIO;
+ pr_err("Can't map frame's registers @ %pa\n", &frame->cntbase);
+ ret = -ENXIO;
+ goto err_release_region;
}
/*
@@ -310,49 +310,56 @@ static int arch_timer_mmio_frame_register(struct platform_device *pdev,
at->rate = arch_timer_get_rate();
irq = at->access == VIRT_ACCESS ? frame->virt_irq : frame->phys_irq;
- ret = devm_request_irq(&pdev->dev, irq, arch_timer_mmio_handler,
- IRQF_TIMER | IRQF_NO_AUTOEN, "arch_mem_timer",
- &at->evt);
+ ret = request_irq(irq, arch_timer_mmio_handler,
+ IRQF_TIMER | IRQF_NO_AUTOEN, "arch_mem_timer",
+ &at->evt);
if (ret) {
- dev_err(&pdev->dev, "Failed to request mem timer irq\n");
- return ret;
+ pr_err("Failed to request mem timer irq for frame @ %pa\n",
+ &frame->cntbase);
+ goto err_iounmap;
}
/* Afer this point, we're not allowed to fail anymore */
arch_timer_mmio_setup(at, irq);
return 0;
+
+err_iounmap:
+ iounmap(at->base);
+err_release_region:
+ release_mem_region(frame->cntbase, frame->size);
+ return ret;
}
-static int of_populate_gt_block(struct platform_device *pdev,
- struct arch_timer *at)
+static int of_populate_gt_block(struct device_node *np, struct arch_timer_mem *gt_block)
{
struct resource res;
- if (of_address_to_resource(pdev->dev.of_node, 0, &res))
+ if (of_address_to_resource(np, 0, &res))
return -EINVAL;
- at->gt_block->cntctlbase = res.start;
- at->gt_block->size = resource_size(&res);
+ gt_block->cntctlbase = res.start;
+ gt_block->size = resource_size(&res);
- for_each_available_child_of_node_scoped(pdev->dev.of_node, frame_node) {
+ for_each_available_child_of_node_scoped(np, frame_node) {
struct arch_timer_mem_frame *frame;
u32 n;
if (of_property_read_u32(frame_node, "frame-number", &n)) {
- dev_err(&pdev->dev, FW_BUG "Missing frame-number\n");
+ pr_err(FW_BUG "Missing frame-number for %pOF\n",
+ frame_node);
return -EINVAL;
}
if (n >= ARCH_TIMER_MEM_MAX_FRAMES) {
- dev_err(&pdev->dev,
- FW_BUG "Wrong frame-number, only 0-%u are permitted\n",
- ARCH_TIMER_MEM_MAX_FRAMES - 1);
+ pr_err(FW_BUG "Wrong frame-number %u for %pOF, only 0-%u are permitted\n",
+ n, frame_node, ARCH_TIMER_MEM_MAX_FRAMES - 1);
return -EINVAL;
}
- frame = &at->gt_block->frame[n];
+ frame = >_block->frame[n];
if (frame->valid) {
- dev_err(&pdev->dev, FW_BUG "Duplicated frame-number\n");
+ pr_err(FW_BUG "Duplicated frame-number %u for %pOF\n",
+ n, frame_node);
return -EINVAL;
}
@@ -371,50 +378,62 @@ static int of_populate_gt_block(struct platform_device *pdev,
return 0;
}
-static int arch_timer_mmio_probe(struct platform_device *pdev)
+static struct arch_timer *arch_timer_mmio_init(struct arch_timer_mem *gt_block,
+ struct device_node *np)
{
+ struct arch_timer *at __free(kfree) = kzalloc_obj(*at);
struct arch_timer_mem_frame *frame;
- struct arch_timer *at;
- struct device_node *np;
int ret;
- np = pdev->dev.of_node;
-
- at = devm_kmalloc(&pdev->dev, sizeof(*at), GFP_KERNEL | __GFP_ZERO);
if (!at)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
+
+ at->gt_block = gt_block;
+
+ frame = find_best_frame(at);
+ if (!frame) {
+ pr_err("Unable to find a suitable frame in timer @ %pa\n",
+ &at->gt_block->cntctlbase);
+ return ERR_PTR(-EINVAL);
+ }
+
+ ret = arch_timer_mmio_frame_register(at, frame, np);
+ if (ret)
+ return ERR_PTR(ret);
+
+ pr_info("mmio timer running at %lu.%02luMHz (%s)\n",
+ (unsigned long)at->rate / 1000000,
+ (unsigned long)(at->rate / 10000) % 100,
+ at->access == VIRT_ACCESS ? "virt" : "phys");
+
+ return_ptr(at);
+}
+
+static int arch_timer_mmio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct arch_timer_mem *gt_block;
+ struct arch_timer *at;
+ int ret;
if (np) {
- at->gt_block = devm_kmalloc(&pdev->dev, sizeof(*at->gt_block),
- GFP_KERNEL | __GFP_ZERO);
- if (!at->gt_block)
+ gt_block = devm_kzalloc(&pdev->dev, sizeof(*gt_block),
+ GFP_KERNEL);
+ if (!gt_block)
return -ENOMEM;
- ret = of_populate_gt_block(pdev, at);
+ ret = of_populate_gt_block(np, gt_block);
if (ret)
return ret;
} else {
- at->gt_block = dev_get_platdata(&pdev->dev);
- }
-
- platform_set_drvdata(pdev, at);
-
- frame = find_best_frame(pdev);
- if (!frame) {
- dev_err(&pdev->dev,
- "Unable to find a suitable frame in timer @ %pa\n",
- &at->gt_block->cntctlbase);
- return -EINVAL;
+ gt_block = dev_get_platdata(&pdev->dev);
}
- ret = arch_timer_mmio_frame_register(pdev, frame);
- if (!ret)
- dev_info(&pdev->dev,
- "mmio timer running at %lu.%02luMHz (%s)\n",
- (unsigned long)at->rate / 1000000,
- (unsigned long)(at->rate / 10000) % 100,
- at->access == VIRT_ACCESS ? "virt" : "phys");
+ at = arch_timer_mmio_init(gt_block, np);
+ if (IS_ERR(at))
+ return PTR_ERR(at);
- return ret;
+ platform_set_drvdata(pdev, at);
+ return 0;
}
static const struct of_device_id arch_timer_mmio_of_table[] = {
--
2.54.0
^ permalink raw reply related
* [PATCH 0/2] clocksource/drivers/arm_arch_timer_mmio: Restore support for early init
From: Stephan Gerhold @ 2026-06-10 17:53 UTC (permalink / raw)
To: Mark Rutland, Marc Zyngier, Daniel Lezcano, Thomas Gleixner,
Sudeep Holla
Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Jack Matthews
Jack reported a regression for some single-core Qualcomm platforms (e.g.
MDM9625, MDM9607) that no longer boot because no timers can be found during
early boot [1]. These platforms rely on an obscure timer setup where the
global Arm MMIO timer (arm,armv7-timer-mem) is used as the only available
timer for the CPU. This setup used to work fine until commit 0f67b56d84b4
("clocksource/drivers/arm_arch_timer_mmio: Switch over to standalone
driver") when the early timer initialization using TIMER_OF_DECLARE() was
removed when moving to the standalone MMIO driver.
There doesn't seem to be any other usable CPU timer on those platforms, so
this series restores the early timer support using TIMER_OF_DECLARE()
inside the new standalone arm_arch_timer_mmio driver. This is pretty ugly,
but I could not think of a better solution so far. I tried to keep the
ugliness for the two probe paths as limited as possible. :-)
If someone has a better idea how to solve this, I would be happy to try it.
[1]: https://lore.kernel.org/r/46A20F89-E208-4091-8B6E-B5C38BF82B42@jackmatthe.ws/
Signed-off-by: Stephan Gerhold <stephan.gerhold@linaro.org>
---
Stephan Gerhold (2):
clocksource/drivers/arm_arch_timer_mmio: Refactor for early init
clocksource/drivers/arm_arch_timer_mmio: Restore support for early init
drivers/clocksource/arm_arch_timer_mmio.c | 180 ++++++++++++++++++++----------
1 file changed, 123 insertions(+), 57 deletions(-)
---
base-commit: 49e02880ec0a8c378e811bc9d85da188d7c6204c
change-id: 20260609-arm-arch-timer-mmio-early-de97155938e4
Best regards,
--
Stephan Gerhold <stephan.gerhold@linaro.org>
^ permalink raw reply
* Re: [PATCH v8 11/12] iommu/arm-smmu-v3: Invoke pm_runtime before hw access
From: Daniel Mentz @ 2026-06-10 17:13 UTC (permalink / raw)
To: Pranjal Shrivastava
Cc: iommu, Will Deacon, Joerg Roedel, Robin Murphy, Jason Gunthorpe,
Mostafa Saleh, Nicolin Chen, Ashish Mhetre, linux-arm-kernel
In-Reply-To: <aihzgtczL99fM-1c@google.com>
On Tue, Jun 9, 2026 at 1:11 PM Pranjal Shrivastava <praan@google.com> wrote:
>
> On Tue, Jun 09, 2026 at 11:34:42AM -0700, Daniel Mentz wrote:
> > On Tue, Jun 9, 2026 at 3:34 AM Pranjal Shrivastava <praan@google.com> wrote:
> > > > I'm not sure if I have a good suggestion here. Have you considered the
> > > > following: Do not call arm_smmu_handle_gerror() from
> > > > arm_smmu_runtime_suspend(). Instead, call disable_irq() at the end of
> > > > the suspend handler (and enable_irq() at the beginning of the resume
> > > > handler)?
> > >
> > > I thought about using disable_irq(), but I think doing it at the
> > > hardware level (IRQ_CTRL) is better.
> > >
> > > By disabling in IRQ_CTRL and keeping the manual arm_smmu_handle_gerror()
> > > call at the end of suspend, we ensure that we don't lose any gerror info
> > > We catch and handle any errors that occurred during the drain/quiesce
> > > phase right before the power-down.
> >
> > I think the beauty of disable_irq() is that it synchronizes any
> > potentially running hard IRQ handler, which helps avoid races.
>
> Alright, I guess we could:
>
> 1. SMMUEN=0
> 2. IRQ_CTRL.gerror=0
Should we call arm_smmu_disable_irqs() here?
> 3. disable_irq();
> 4. handle_gerror(); at the end of suspend
^ permalink raw reply
* Re: [PATCH v8 07/12] iommu/arm-smmu-v3: Add CMDQ_PROD_STOP_FLAG to gate CMDQ submissions
From: Daniel Mentz @ 2026-06-10 17:37 UTC (permalink / raw)
To: Pranjal Shrivastava
Cc: iommu, Will Deacon, Joerg Roedel, Robin Murphy, Jason Gunthorpe,
Mostafa Saleh, Nicolin Chen, Ashish Mhetre, linux-arm-kernel
In-Reply-To: <aihiPQ2mdqMm13Cd@google.com>
On Tue, Jun 9, 2026 at 11:58 AM Pranjal Shrivastava <praan@google.com> wrote:
>
> On Tue, Jun 09, 2026 at 11:20:52AM -0700, Daniel Mentz wrote:
> > On Tue, Jun 9, 2026 at 3:05 AM Pranjal Shrivastava <praan@google.com> wrote:
> > > >
> > > > > Even if the worker CPU reorders the PTE write after the STOP_FLAG check,
> > > > > it is benign because the SMMU is incapable of fetching that (or any) PTE
> > > > > while the gate is closed. Because GATE_CLOSED == SMMUEN = 0, implying no
> > > > > access to any HW structures whatsoever.
> > > > >
> > > > > The real synchronization happens in the Resume Path:
> > > > >
> > > > > 1. arm_smmu_device_reset() clears all caches / TLBs.
> > > > > (None of these can have entries before SMMUEN=1)
> > > > >
> > > > > 2. We execute a full smp_mb() before setting SMMUEN=1. (that's why we
> > > > > need smp_mb before SMMUEN=1). This barrier ensures that any PTE
> > > > > writes made by any thread—including those that were elided while the
> > > > > gate was closed, are globally visible before the SMMU hardware starts
> > > > > fetching into TLBs again. (This is why Jason suggested this in v6 [1])
> > > >
> > > > A barrier on one CPU has no bearing on whether writes by any other CPU
> > > > can be observed by any particular agent in the system.
> > > >
> > > > Let's compare this with the long comment in
> > > > arm_smmu_domain_inv_range() which is what I believe Jason was
> > > > referring to. In that example, you see smp_mb() in the code path on
> > > > CPU0 and dma_wmb() in the code path on CPU1. Hence, barriers exist on
> > > > both sides. If you compare the runtime PM design with
> > > > arm_smmu_domain_inv_range(), then smp_mb() belongs in the CPU thread
> > > > that performs the translation table updates not the one that performs
> > > > the suspend/resume operation.
> > > >
> > >
> > > I might be missing something here, so please bear with me. My
> > > understanding it that's needed because the IOMMU is live & actively
> > > caching, which is not true for our case.
> >
> > I think the "invs" design (Per-domain invalidation array) is more
> > similar than you think! An SMMU being absent from invs is equivalent
> > to the STOP flag, and the STE pointing to TTB0 is roughly the
> > equivalent of SMMEN=1 i.e. the IOMMU is not actively caching a
> > particular translation domain until an STE (or CD) points to it.
> >
> > > [Assuming we use non-relaxed semantics & ordering for the STOP flag,
> > > i.e. set STOP_FLAG + barrier & clear STOP_FLAG (implicit dma_wmb())]
> > >
> > > In our case, during the resume op, we first clear the STOP_FLAG before
> > > setting SMMUEN=1 in program order. Thus, any PTE invalidations occurring
> > > before SMMUEN=1 are executed, i.e. EVEN when the SMMU is guaranteed not
> > > to access any structures, we've resumed invalidations.
> >
> > "[...] we first clear the STOP_FLAG before setting SMMUEN=1 in program
> > order." I think this should be modified to "we first clear the
> > STOP_FLAG and ensure that the cleared STOP_FLAG is observable by all
> > other CPUs before setting SMMUEN=1"
> >
>
> Ack. The goal was to explain the algorithm for this thread, I won't be
> commenting it in code. Are you suggesting I should convert my
> explaination of the algorithm above into in-line comments and make sure
> to include the STOP_FLAG observability part?
I believe there would be a benefit to having a comment in the code
that states the requirements for the STOP_FLAG observability.
Something along the lines of either of the following:
* SMMU must be disabled any time another CPU can observe the STOP_FLAG
* Other CPUs must (a) observe the STOP flag only after the SMMU is
disabled, and (b) observe the cleared STOP flag before the SMMU is
re-enabled.
> >
> > I would define a set of invariants:
> >
> > * If an agent observes the STOP flag, it is guaranteed that SMMUEN=0
> > (with ABORT set) at the time of observation.
> > * Any transition from a set STOP flag to SMMUEN=1 involves an
> > invalidate-all operation prior to setting SMMUEN=1
> >
> > Hence, if a CPU observes the STOP flag, it is assured that (a)
> > transactions are blocked and (b) if the SMMU is ever re-enabled, an
> > invalidate-all is performed prior to it being enabled.
> >
> > I would then argue that all operations support these invariants. For
> > example, we need proper barriers in the iommu_unmap path to ensure
> > that the STOP flag is only checked *after* the translation table
> > update is made. Hence, we need a memory barrier.
> >
> > I look at it this way: Every elided invalidation creates an
> > "invalidation deficit", and this deficit is tolerable for two reasons:
> > (a) SMMU blocks all transactions while there is a deficit. (b) An
> > invalidate-all eliminates any deficit accrued while the STOP flag was
> > set.
>
> Ack, which means you agree with the design proposed in my last reply.
> I'll document these invariants in line if that's what you're suggesting
> here?
Yes, I believe we are in agreement, and yes, I think documenting these
invariants would be beneficial.
[...]
> >
> >
> > > HW structures not accessed means no TLB / CFG
> > > cache accesses as well according to the spec.
> > >
> > > [CPU1] ==> PTE update => Invalidate => Succeeds (although SMMUEN = 0)
> > >
> > > [CPU0] GBPA.Abort set ==> Txns are blocked
> > >
> > > [CPU2] => PTE update => Invalidate => Succeeds [Txns blocked + SMMUEN=0]
> > >
> > > [CPU0] ==> SET STOP_FLAG ==> Elision begins
> > >
> > > [CPU3] ==> PTE update ==> Invalidation ==> Elided [Txns blocked + SMMUEN=0]
> > >
> > > Hence, the races in the suspend sequence are handled correctly.
> >
> > I'm not sure if this description demonstrates that every possible race
> > is handled correctly. If I compare this with Nicolin's presentation in
> > arm_smmu_domain_inv_range, I like that presentation, as it explicitly
> > mentions loads and barriers. For example, it has an smp_mb() followed
> > by "// load the updated invs". I think you should make have something
> > like "smp_mb() ; CHECK STOP_FLAG" in your presentation. Currently, the
> > STOP_FLAG checking is somehow implicit in "Invalidation".
>
> Ack. The goal of this diagram was to explain the working of the design,
> this is NOT the comment/document I plan to include in code.
>
> I'll add this as an in-line comment if that's what you're suggesting? OR
> are you also suggesting I should have this in my cover letter?
In arm_smmu_domain_inv_range(), there's Nicolin's sequence diagram
that describes how installing a new domain is synchronized with PTE
updates and subsequent TLBIs. I would recommend adding a similar
diagram that shows how suspend and resume are synchronized with PTE
updates and TLBIs.
Thanks
Daniel
^ permalink raw reply
* Re: [PATCH v2] EDAC/synopsys: Fix cleanup on injection sysfs failure
From: Borislav Petkov @ 2026-06-10 17:27 UTC (permalink / raw)
To: Yuho Choi
Cc: Tony Luck, Michal Simek, linux-edac, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260605125417.2348115-1-dbgh9129@gmail.com>
On Fri, Jun 05, 2026 at 08:54:17AM -0400, Yuho Choi wrote:
> edac_create_sysfs_attributes() creates inject_data_error before
> inject_data_poison. If the second file creation fails, the first file is
> left behind.
>
> The same failure path runs after edac_mc_add_mc() has registered the
> memory controller with the EDAC core. Jumping directly to edac_mc_free()
> skips edac_mc_del_mc() and leaves the registered controller state
> unwound incorrectly.
>
> Remove inject_data_error when inject_data_poison creation fails, and
> route the probe failure through edac_mc_del_mc() before freeing mci.
>
> Fixes: 1a81361f75d8 ("EDAC, synopsys: Add Error Injection support for ZynqMP DDR controller")
> Signed-off-by: Yuho Choi <dbgh9129@gmail.com>
> ---
> Changes in v2:
> - Remove the CONFIG_EDAC_DEBUG-guarded del_mc label.
> - Call edac_mc_del_mc() inline before jumping to free_edac_mc when
> edac_create_sysfs_attributes() fails.
>
> drivers/edac/synopsys_edac.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
https://sashiko.dev/#/patchset/20260605125417.2348115-1-dbgh9129%40gmail.com
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply
* [PATCH v5] soc: aspeed: lpc-snoop: Fix usercopy overflow in snoop_file_read
From: Karthikeyan KS @ 2026-06-10 17:23 UTC (permalink / raw)
To: andrew
Cc: joel, andrew, Kees Cook, linux-arm-kernel, linux-aspeed,
linux-kernel, linux-hardening, Karthikeyan KS, stable
In-Reply-To: <033f2657ae6a94ad13d22f717a2900afb75d892d.camel@codeconstruct.com.au>
put_fifo_with_discard() acts as both producer and consumer on the kfifo:
it calls kfifo_skip() (advances out) and kfifo_put() (advances in) from
the IRQ handler without synchronizing with snoop_file_read(), which also
consumes via kfifo_to_user(). On SMP systems this concurrent access can
leave (in - out) larger than the ring buffer, so __kfifo_to_user()'s clamp
to (in - out) is ineffective and kfifo_copy_to_user() can attempt a
copy_to_user() past the kmalloc-2k backing store:
usercopy: Kernel memory exposure attempt detected from SLUB object
'kmalloc-2k' (offset 0, size 2049)!
kernel BUG at mm/usercopy.c!
Call trace:
usercopy_abort
__check_heap_object
__check_object_size
kfifo_copy_to_user
__kfifo_to_user
snoop_file_read
vfs_read
Serialize kfifo access with a per-channel spinlock. The reader drains
into a bounce buffer under the lock with kfifo_out_spinlocked() and then
copies to userspace after dropping it, since copy_to_user() may sleep on
a page fault.
Fixes: 3772e5da4454 ("drivers/misc: Aspeed LPC snoop output using misc chardev")
Cc: stable@vger.kernel.org
Signed-off-by: Karthikeyan KS <karthiproffesional@gmail.com>
---
Andrew,
Thanks for the review.
Changes since v4:
- Use __free(kfree) for automatic cleanup
- Allocate clamped count instead of full SNOOP_FIFO_SIZE
- Use kfifo_out_spinlocked() in snoop_file_read
- Use scoped_guard(spinlock) in put_fifo_with_discard
drivers/soc/aspeed/aspeed-lpc-snoop.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c
index b03310c0830d..c9c87a794228 100644
--- a/drivers/soc/aspeed/aspeed-lpc-snoop.c
+++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c
@@ -11,6 +11,7 @@
*/
#include <linux/bitops.h>
+#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/dev_printk.h>
#include <linux/interrupt.h>
@@ -74,6 +75,7 @@ struct aspeed_lpc_snoop_channel_cfg {
struct aspeed_lpc_snoop_channel {
const struct aspeed_lpc_snoop_channel_cfg *cfg;
bool enabled;
+ spinlock_t lock; /* serialises @fifo: irq producer vs reader */
struct kfifo fifo;
wait_queue_head_t wq;
struct miscdevice miscdev;
@@ -114,6 +116,7 @@ static ssize_t snoop_file_read(struct file *file, char __user *buffer,
size_t count, loff_t *ppos)
{
struct aspeed_lpc_snoop_channel *chan = snoop_file_to_chan(file);
+ u8 *buf __free(kfree) = NULL;
unsigned int copied;
int ret = 0;
@@ -125,9 +128,16 @@ static ssize_t snoop_file_read(struct file *file, char __user *buffer,
if (ret == -ERESTARTSYS)
return -EINTR;
}
- ret = kfifo_to_user(&chan->fifo, buffer, count, &copied);
- if (ret)
- return ret;
+
+ count = min_t(size_t, count, SNOOP_FIFO_SIZE);
+
+ buf = kmalloc(count, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ copied = kfifo_out_spinlocked(&chan->fifo, buf, count, &chan->lock);
+ if (copied && copy_to_user(buffer, buf, copied))
+ return -EFAULT;
return copied;
}
@@ -153,9 +163,11 @@ static void put_fifo_with_discard(struct aspeed_lpc_snoop_channel *chan, u8 val)
{
if (!kfifo_initialized(&chan->fifo))
return;
- if (kfifo_is_full(&chan->fifo))
- kfifo_skip(&chan->fifo);
- kfifo_put(&chan->fifo, val);
+ scoped_guard(spinlock, &chan->lock) {
+ if (kfifo_is_full(&chan->fifo))
+ kfifo_skip(&chan->fifo);
+ kfifo_put(&chan->fifo, val);
+ }
wake_up_interruptible(&chan->wq);
}
@@ -228,6 +240,7 @@ static int aspeed_lpc_enable_snoop(struct device *dev,
return -EBUSY;
init_waitqueue_head(&channel->wq);
+ spin_lock_init(&channel->lock);
channel->cfg = cfg;
channel->miscdev.minor = MISC_DYNAMIC_MINOR;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] Bluetooth: hci_bcm4377: Use named initializers for pci_device_id array
From: Luiz Augusto von Dentz @ 2026-06-10 17:13 UTC (permalink / raw)
To: Uwe Kleine-König (The Capable Hub)
Cc: Sven Peter, Janne Grunau, Neal Gompa, Marcel Holtmann,
Markus Schneider-Pargmann, asahi, linux-arm-kernel,
linux-bluetooth, linux-kernel
In-Reply-To: <aimXkX4FC4JVxt6q@monoceros>
Hi Uwe,
On Wed, Jun 10, 2026 at 12:59 PM Uwe Kleine-König (The Capable Hub)
<u.kleine-koenig@baylibre.com> wrote:
>
> On Mon, May 04, 2026 at 06:09:40PM +0200, Uwe Kleine-König (The Capable Hub) wrote:
> > Initializing a struct using list initializers is hard to read, compared
> > to that using named initializers is more ideomatic. Convert the macro
> > used to assign values in the driver's pci_device_id array accordingly.
> >
> > This change doesn't introduce any changes to the compiled array on an
> > x86 and an arm64 build.
> >
> > Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
> > ---
> > Hello,
> >
> > this is a preparing change for making struct pci_device_id::driver_data an
> > anonymous union (similar to
> > https://lore.kernel.org/all/cover.1776579304.git.u.kleine-koenig@baylibre.com/).
> > This requires named initializers for .driver_data. But even without that
> > this is a nice cleanup making the macro better readable.
> >
> > Gcc is happy with simplifying the assignment further using
> > PCI_VDEVICE(BROADCOM, BCM ## id ## _DEVICE_ID), but this is a bit fishy
> > because PCI_VDEVICE also assigns .class and .class_mask (using list
> > initializers), so I didn't convert that.
>
> In the meantime I learned that doing that would break W=1 builds, so it
> was a good choice to not go that path.
>
> > Once all pci_device_id use
> > named initializers, the two zeros can be dropped from PCI_VDEVICE and
> > this entry simplified accordingly.
>
> Is this patch still on someone's radar? Ideally for application in time
> for 7.2-rc1?
It is no longer in patchwork so if you really want to get in please resend.
> Best regards
> Uwe
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH] ARM: footbridge: convert to sparse IRQs
From: Dmitry Torokhov @ 2026-06-10 17:03 UTC (permalink / raw)
To: Ethan Nelson-Moore
Cc: Arnd Bergmann, linux-arm-kernel, linux-input, linux-serial,
Russell King, Greg Kroah-Hartman, Jiri Slaby, Russell King,
Linus Walleij, Kees Cook, Nathan Chancellor,
Sebastian Andrzej Siewior, Steven Rostedt, Thomas Weißschuh,
Peter Zijlstra
In-Reply-To: <CADkSEUhh1NdOMTHVsErhqzyCpDGFA-FkNFaWp94e9LnB3njxqw@mail.gmail.com>
On Mon, Jun 08, 2026 at 10:13:50AM -0700, Ethan Nelson-Moore wrote:
> Hi, Arnd,
>
> On Mon, Jun 8, 2026 at 10:11 AM Arnd Bergmann <arnd@arndb.de> wrote:
> > I think this is correct, as footbridge is the only one that selects
> > CONFIG_ARCH_MIGHT_HAVE_PC_SERIO and defines I8042_KBD_IRQ on arm.
>
> I came to the same conclusion.
I see. In this case:
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> # for input
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Bluetooth: hci_bcm4377: Use named initializers for pci_device_id array
From: Uwe Kleine-König (The Capable Hub) @ 2026-06-10 16:59 UTC (permalink / raw)
To: Sven Peter, Janne Grunau, Neal Gompa, Marcel Holtmann,
Luiz Augusto von Dentz
Cc: Markus Schneider-Pargmann, asahi, linux-arm-kernel,
linux-bluetooth, linux-kernel
In-Reply-To: <20260504160940.2168650-2-u.kleine-koenig@baylibre.com>
[-- Attachment #1: Type: text/plain, Size: 1473 bytes --]
On Mon, May 04, 2026 at 06:09:40PM +0200, Uwe Kleine-König (The Capable Hub) wrote:
> Initializing a struct using list initializers is hard to read, compared
> to that using named initializers is more ideomatic. Convert the macro
> used to assign values in the driver's pci_device_id array accordingly.
>
> This change doesn't introduce any changes to the compiled array on an
> x86 and an arm64 build.
>
> Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
> ---
> Hello,
>
> this is a preparing change for making struct pci_device_id::driver_data an
> anonymous union (similar to
> https://lore.kernel.org/all/cover.1776579304.git.u.kleine-koenig@baylibre.com/).
> This requires named initializers for .driver_data. But even without that
> this is a nice cleanup making the macro better readable.
>
> Gcc is happy with simplifying the assignment further using
> PCI_VDEVICE(BROADCOM, BCM ## id ## _DEVICE_ID), but this is a bit fishy
> because PCI_VDEVICE also assigns .class and .class_mask (using list
> initializers), so I didn't convert that.
In the meantime I learned that doing that would break W=1 builds, so it
was a good choice to not go that path.
> Once all pci_device_id use
> named initializers, the two zeros can be dropped from PCI_VDEVICE and
> this entry simplified accordingly.
Is this patch still on someone's radar? Ideally for application in time
for 7.2-rc1?
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* [PATCH v3] arm64: errata: Workaround NVIDIA Olympus device store/load ordering erratum
From: Shanker Donthineni @ 2026-06-10 16:48 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Vladimir Murzin
Cc: Jason Gunthorpe, linux-arm-kernel, Mark Rutland, linux-kernel,
linux-doc, Shanker Donthineni, Vikram Sethi, Jason Sequeira
On systems with NVIDIA Olympus cores, a Device-nGnR* load can be
observed by a peripheral before an older, non-overlapping Device-nGnR*
store to the same peripheral. This breaks the program-order guarantee
that software expects for Device-nGnR* accesses and can leave a
peripheral in an incorrect state, as a load is observed before an
earlier store takes effect.
The erratum can occur only when all of the following apply:
- A PE executes a Device-nGnR* store followed by a younger
Device-nGnR* load.
- The store is not a store-release.
- The accesses target the same peripheral and do not overlap in bytes.
- There is at most one intervening Device-nGnR* store in program
order, and there are no intervening Device-nGnR* loads.
- There is no DSB, and no DMB that orders loads, between the store and
the load.
- Specific micro-architectural and timing conditions occur.
Promote the raw MMIO store helpers (__raw_writeb/w/l/q) from plain str*
to stlr* (Store-Release), which removes the "store is not a
store-release" condition for every device write the kernel issues.
Because writel() and writel_relaxed() are both built on __raw_writel()
in asm-generic/io.h, patching the raw variants covers both the
non-relaxed and relaxed APIs without touching the higher layers. Note
that writel()'s own barrier sits before the store, so it does not order
the store against a subsequent readl(); the store-release promotion is
what provides that ordering.
Like ARM64_ERRATUM_832075 on the load side, the change is gated on a new
ARM64_WORKAROUND_DEVICE_STORE_RELEASE capability and only activated on
parts that match MIDR_NVIDIA_OLYMPUS, so unaffected CPUs continue to use
the plain str* sequence.
Note: stlr* only supports base-register addressing, so affected CPUs use
a base-register stlr* path. Unaffected CPUs keep the original
offset-addressed str* sequence introduced by commit d044d6ba6f02
("arm64: io: permit offset addressing").
The __const_memcpy_toio_aligned32() and __const_memcpy_toio_aligned64()
helpers are left unchanged. These helpers are intended for
write-combining mappings, which are Normal-NC on arm64. Replacing their
contiguous str* groups would defeat the write-combining behavior used to
improve store performance.
Co-developed-by: Vikram Sethi <vsethi@nvidia.com>
Signed-off-by: Vikram Sethi <vsethi@nvidia.com>
Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
Changes since v2:
- Reworked the raw MMIO write helpers so unaffected CPUs keep the
existing offset-addressed STR sequence, while affected CPUs use the
base-register STLR path.
- Updated the commit message to match the code changes.
- Rebased on top of the arm64 for-next/errata branch:
https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=for-next/errata
Changes since v1:
- Updated the commit message based on feedback from Vladimir Murzin.
Documentation/arch/arm64/silicon-errata.rst | 2 ++
arch/arm64/Kconfig | 23 ++++++++++++++++
arch/arm64/include/asm/io.h | 30 +++++++++++++++++++++
arch/arm64/kernel/cpu_errata.c | 8 ++++++
arch/arm64/tools/cpucaps | 1 +
5 files changed, 64 insertions(+)
diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index ad09bbb10da80..fc45125dc2f80 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -298,6 +298,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| NVIDIA | Carmel Core | N/A | NVIDIA_CARMEL_CNP_ERRATUM |
+----------------+-----------------+-----------------+-----------------------------+
+| NVIDIA | Olympus core | T410-OLY-1027 | NVIDIA_OLYMPUS_1027_ERRATUM |
++----------------+-----------------+-----------------+-----------------------------+
| NVIDIA | Olympus core | T410-OLY-1029 | ARM64_ERRATUM_4118414 |
+----------------+-----------------+-----------------+-----------------------------+
| NVIDIA | T241 GICv3/4.x | T241-FABRIC-4 | N/A |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c65cef81be86a..d633eb70de1ac 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -564,6 +564,29 @@ config ARM64_ERRATUM_832075
If unsure, say Y.
+config NVIDIA_OLYMPUS_1027_ERRATUM
+ bool "NVIDIA Olympus: device store/load ordering erratum"
+ default y
+ help
+ This option adds an alternative code sequence to work around an
+ NVIDIA Olympus core erratum where a Device-nGnR* store can be
+ observed by a peripheral after a younger Device-nGnR* load to the
+ same peripheral. This breaks the program order that drivers rely
+ on for MMIO and can leave a device in an incorrect state.
+
+ The workaround promotes the raw MMIO store helpers
+ (__raw_writeb/w/l/q) to Store-Release (STLR), which restores the
+ required ordering. Because writel() and writel_relaxed() are built
+ on __raw_writel(), both are covered without changes to the higher
+ layers.
+
+ The fix is applied through the alternatives framework, so enabling
+ this option does not by itself activate the workaround: it is
+ patched in only when an affected CPU is detected, and is a no-op on
+ unaffected CPUs.
+
+ If unsure, say Y.
+
config ARM64_ERRATUM_834220
bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault (rare)"
depends on KVM
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 8cbd1e96fd50b..801223e754c90 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -22,10 +22,22 @@
/*
* Generic IO read/write. These perform native-endian accesses.
*/
+static __always_inline bool arm64_needs_device_store_release(void)
+{
+ return alternative_has_cap_unlikely(
+ ARM64_WORKAROUND_DEVICE_STORE_RELEASE);
+}
+
#define __raw_writeb __raw_writeb
static __always_inline void __raw_writeb(u8 val, volatile void __iomem *addr)
{
volatile u8 __iomem *ptr = addr;
+
+ if (arm64_needs_device_store_release()) {
+ asm volatile("stlrb %w0, [%1]" : : "rZ" (val), "r" (addr));
+ return;
+ }
+
asm volatile("strb %w0, %1" : : "rZ" (val), "Qo" (*ptr));
}
@@ -33,6 +45,12 @@ static __always_inline void __raw_writeb(u8 val, volatile void __iomem *addr)
static __always_inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
volatile u16 __iomem *ptr = addr;
+
+ if (arm64_needs_device_store_release()) {
+ asm volatile("stlrh %w0, [%1]" : : "rZ" (val), "r" (addr));
+ return;
+ }
+
asm volatile("strh %w0, %1" : : "rZ" (val), "Qo" (*ptr));
}
@@ -40,6 +58,12 @@ static __always_inline void __raw_writew(u16 val, volatile void __iomem *addr)
static __always_inline void __raw_writel(u32 val, volatile void __iomem *addr)
{
volatile u32 __iomem *ptr = addr;
+
+ if (arm64_needs_device_store_release()) {
+ asm volatile("stlr %w0, [%1]" : : "rZ" (val), "r" (addr));
+ return;
+ }
+
asm volatile("str %w0, %1" : : "rZ" (val), "Qo" (*ptr));
}
@@ -47,6 +71,12 @@ static __always_inline void __raw_writel(u32 val, volatile void __iomem *addr)
static __always_inline void __raw_writeq(u64 val, volatile void __iomem *addr)
{
volatile u64 __iomem *ptr = addr;
+
+ if (arm64_needs_device_store_release()) {
+ asm volatile("stlr %x0, [%1]" : : "rZ" (val), "r" (addr));
+ return;
+ }
+
asm volatile("str %x0, %1" : : "rZ" (val), "Qo" (*ptr));
}
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index d597896b0f7f3..b096d9acca578 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -838,6 +838,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
ERRATA_MIDR_ALL_VERSIONS(MIDR_NVIDIA_CARMEL),
},
#endif
+#ifdef CONFIG_NVIDIA_OLYMPUS_1027_ERRATUM
+ {
+ /* NVIDIA Olympus core */
+ .desc = "NVIDIA Olympus device load/store ordering erratum",
+ .capability = ARM64_WORKAROUND_DEVICE_STORE_RELEASE,
+ ERRATA_MIDR_ALL_VERSIONS(MIDR_NVIDIA_OLYMPUS),
+ },
+#endif
#ifdef CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
{
/*
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 811c2479e82d6..d367257bf7703 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -120,6 +120,7 @@ WORKAROUND_CAVIUM_TX2_219_PRFM
WORKAROUND_CAVIUM_TX2_219_TVM
WORKAROUND_CLEAN_CACHE
WORKAROUND_DEVICE_LOAD_ACQUIRE
+WORKAROUND_DEVICE_STORE_RELEASE
WORKAROUND_NVIDIA_CARMEL_CNP
WORKAROUND_PMUV3_IMPDEF_TRAPS
WORKAROUND_QCOM_FALKOR_E1003
--
2.43.0
^ permalink raw reply related
* Re: [PATCH 2/2] ufs: mediatek: Implement get_hba_nortt callback for RTT capability
From: Bart Van Assche @ 2026-06-10 16:46 UTC (permalink / raw)
To: ed.tsai, alim.akhtar, avri.altman, James.Bottomley,
martin.petersen, linux-scsi
Cc: linux-kernel, linux-arm-kernel, linux-mediatek, wsd_upstream,
peter.wang, alice.chao, naomi.chu, chun-hung.wu
In-Reply-To: <20260609103856.676222-3-ed.tsai@mediatek.com>
On 6/9/26 3:38 AM, ed.tsai@mediatek.com wrote:
> Implement the get_hba_nortt callback to handle platform-specific RTT
> capability differences:
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
^ permalink raw reply
* Re: [PATCH 1/2] ufs: core: Add get_hba_nortt callback for vendor-specific RTT capability
From: Bart Van Assche @ 2026-06-10 16:46 UTC (permalink / raw)
To: ed.tsai, alim.akhtar, avri.altman, James.Bottomley,
martin.petersen, linux-scsi
Cc: linux-kernel, linux-arm-kernel, linux-mediatek, wsd_upstream,
peter.wang, alice.chao, naomi.chu, chun-hung.wu
In-Reply-To: <20260609103856.676222-2-ed.tsai@mediatek.com>
On 6/9/26 3:38 AM, ed.tsai@mediatek.com wrote:
> diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
> index cfbc75d8df83..13d0d7798294 100644
> --- a/include/ufs/ufshcd.h
> +++ b/include/ufs/ufshcd.h
> @@ -370,7 +370,6 @@ struct ufshcd_tx_eq_params {
> /**
> * struct ufs_hba_variant_ops - variant specific callbacks
> * @name: variant name
> - * @max_num_rtt: maximum RTT supported by the host
> * @init: called when the driver is initialized
> * @exit: called to cleanup everything done in init
> * @set_dma_mask: For setting another DMA mask than indicated by the 64AS
> @@ -415,10 +414,11 @@ struct ufshcd_tx_eq_params {
> * @get_rx_fom: called to get Figure of Merit (FOM) value.
> * @tx_eqtr_notify: called before and after TX Equalization Training procedure
> * to allow platform vendor specific configs to take place.
> + * @get_hba_nortt: called to get maximum number of outstanding RTTs supported by
> + * the controller.
> */
> struct ufs_hba_variant_ops {
> const char *name;
> - int max_num_rtt;
> int (*init)(struct ufs_hba *);
> void (*exit)(struct ufs_hba *);
> u32 (*get_ufs_hci_version)(struct ufs_hba *);
> @@ -477,6 +477,7 @@ struct ufs_hba_variant_ops {
> int (*tx_eqtr_notify)(struct ufs_hba *hba,
> enum ufs_notify_change_status status,
> struct ufs_pa_layer_attr *pwr_mode);
> + int (*get_hba_nortt)(struct ufs_hba *hba);
> };
A patch series should be bisectable. Removing max_num_rtt from struct
ufs_hba_variant_ops before the code is removed from the MediaTek driver
that sets that variable introduces a build break. Please keep
'max_num_rtt' in this patch and add a third patch to this series that
removes 'max_num_rtt'.
Thanks,
Bart.
^ permalink raw reply
* Re: [PATCH v2 1/2] dt-bindings: arm: rockchip: Add HINLINK H28K
From: Conor Dooley @ 2026-06-10 16:43 UTC (permalink / raw)
To: Chukun Pan
Cc: Heiko Stuebner, Rob Herring, Conor Dooley, Krzysztof Kozlowski,
linux-arm-kernel, linux-rockchip, linux-kernel, devicetree
In-Reply-To: <20260610100006.366963-2-amadeus@jmu.edu.cn>
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v6 04/20] dma-pool: track decrypted atomic pools and select them via attrs
From: Jason Gunthorpe @ 2026-06-10 16:41 UTC (permalink / raw)
To: Aneesh Kumar K.V
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Jiri Pirko,
Michael Kelley
In-Reply-To: <yq5afr2uzum9.fsf@kernel.org>
On Wed, Jun 10, 2026 at 01:37:26PM +0530, Aneesh Kumar K.V wrote:
> Jason Gunthorpe <jgg@ziepe.ca> writes:
>
> > On Thu, Jun 04, 2026 at 02:09:43PM +0530, Aneesh Kumar K.V (Arm) wrote:
> >> struct page *dma_alloc_from_pool(struct device *dev, size_t size,
> >> - void **cpu_addr, gfp_t gfp,
> >> + void **cpu_addr, gfp_t gfp, unsigned long attrs,
> >> bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
> >> {
> >> - struct gen_pool *pool = NULL;
> >> + struct dma_gen_pool *dma_pool = NULL;
> >> struct page *page;
> >> bool pool_found = false;
> >>
> >> - while ((pool = dma_guess_pool(pool, gfp))) {
> >> + while ((dma_pool = dma_guess_pool(dma_pool, gfp))) {
> >> +
> >> + if (dma_pool->unencrypted != !!(attrs & DMA_ATTR_CC_SHARED))
> >> + continue;
> >
> > I don't think you should be overloading DMA_ATTR_CC_SHARED like this.
> >
> > /*
> > * DMA_ATTR_CC_SHARED is not a caller-visible dma_alloc_*()
> > * attribute. The direct allocator uses it internally after it has
> > * decided that the backing pages must be shared/decrypted, so the
> > * rest of the allocation path can consistently select DMA addresses,
> > * choose compatible pools and restore encryption on free.
> > */
> > if (attrs & DMA_ATTR_CC_SHARED)
> > return NULL;
> >
> > if (force_dma_unencrypted(dev)) {
> > attrs |= DMA_ATTR_CC_SHARED;
> > mark_mem_decrypt = true;
> > }
> >
> > It is fine to have a bit inside the attrs that is only used by the
> > internal logic, but it needs to have a clearer name
> > __DMA_ATTR_REQUIRE_CC_SHARED perhaps.
> >
>
> Are you suggesting adding another attribute in addition to
> DMA_ATTR_CC_SHARED?
>
> Is the idea that __DMA_ATTR_REQUIRE_CC_SHARED would be used in the
> allocation path to request a CC_SHARED allocation, while
> DMA_ATTR_CC_SHARED would be used in the mapping path to describe the
> attribute of the address?
Yeah, it is a thought at least
Maybe a comment is good enough.
I just find it hard to follow when we have this dual usage. Like the
code above for dma_pool->unencrypted is completely wrong if it is an
"attribute of an address". Easy to cut & paste that into the wrong
context.
Especially if you move things up higher.. having the alloc set both
CC_SHARED and REQUIRE_CC_SHARED or maybe ALLOC_CC_SHARED would make it
clearer that the alloc code lives under that callchain
Jason
^ permalink raw reply
* Re: [PATCH] KVM: arm64: Hold kvm->mmu_lock while initialising vcpu->arch.vncr_tlb
From: Yosry Ahmed @ 2026-06-10 16:39 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvmarm, kvm, linux-arm-kernel, Steffen Eiden, Joey Gouly,
Suzuki K Poulose, Oliver Upton, Zenghui Yu
In-Reply-To: <868q8mu0hr.wl-maz@kernel.org>
On Wed, Jun 10, 2026 at 3:57 AM Marc Zyngier <maz@kernel.org> wrote:
>
> On Tue, 09 Jun 2026 18:57:26 +0100,
> Yosry Ahmed <yosry@kernel.org> wrote:
> >
> > > > If yes, I think the code looks confusing, at least to a layman like
> > > > myself. It initially seems like the lock protects against concurrent
> > > > initializations, but then the NULL check is not done again under the
> > > > lock. The goal of the lock is not clear without the original report.
> > > >
> > > > Mayeb it's clearer to explicitly use barriers if the goal is preventing
> > > > reordering?
> > >
> > > This would require both the initialisation of vncr_tlb to use a store
> > > release, *and* all the other call sites to use a load acquire.
> > >
> > > I really don't think it is worth the churn, nor the (very small)
> > > burden on the readers.
> >
> > That's fair. I was mainly just pointing out my initial confusion and
> > that others may share it. Avoiding the churn on the readers' side is
> > understandable. Maybe a comment here would help explain why the lock
> > needs to be held?
>
> I have added this:
>
> /*
> * Taking the lock on assignment ensures that the TLB is
> * seen as initialised when following the pointer (release
> * semantics of the unlock), and avoids having acquires on
> * each user which already take the lock.
> */
Looks good, thank you!
^ 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