[PATCH 3/4] wifi: mt76: sdio: use CMD52 to mask and unmask the interrupt

From: Ryan Brue

Date: Mon Oct 26 2026 - 15:11:56 EST


WHLPCR_INT_EN_SET and WHLPCR_INT_EN_CLR live in the low byte of WHLPCR.
Writing them with sdio_writel() costs a 4-byte CMD53 with a data phase,
three times per pass of the txrx worker. A byte write is a CMD52, as
MediaTek's own driver uses for the same register.

On an MT7663 SDIO module (mt7663s, MSDC2 at SDR50) the writes take about
17 us instead of about 40 us each.
The worker is shared with mt7921s, which has the same WHLPCR layout;
only the MT7663 was tested.

Signed-off-by: Ryan Brue <ryanbrue.dev@xxxxxxxxx>
---
drivers/net/wireless/mediatek/mt76/sdio_txrx.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
index 3f314e8e1e69..311c31e87ee5 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
@@ -319,7 +319,7 @@ void mt76s_txrx_worker(struct mt76_sdio *sdio)

/* disable interrupt */
sdio_claim_host(sdio->func);
- sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
+ sdio_writeb(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
sdio_release_host(sdio->func);

do {
@@ -351,7 +351,7 @@ void mt76s_txrx_worker(struct mt76_sdio *sdio)

/* enable interrupt */
sdio_claim_host(sdio->func);
- sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL);
+ sdio_writeb(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL);
sdio_release_host(sdio->func);
}
EXPORT_SYMBOL_GPL(mt76s_txrx_worker);
@@ -365,7 +365,7 @@ void mt76s_sdio_irq(struct sdio_func *func)
test_bit(MT76_MCU_RESET, &dev->phy.state))
return;

- sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
+ sdio_writeb(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
mt76_worker_schedule(&sdio->txrx_worker);
}
EXPORT_SYMBOL_GPL(mt76s_sdio_irq);

--
2.55.0