* [PATCH v4 0/1] dt-bindings: remoteproc: mtk,scp: Allow multiple memory regions for MT8188
From: Arnab Layek @ 2026-05-20 11:26 UTC (permalink / raw)
To: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek
Cc: robh, krzk+dt, conor+dt, matthias.bgg, angelogioacchino.delregno,
andersson, mathieu.poirier, linux-remoteproc,
Project_Global_Chrome_Upstream_Group, Arnab Layek
This patch updates the mtk,scp dt-binding schema to support MT8188's
requirement for 1-2 memory regions while maintaining strict backward
compatibility for other MediaTek SoCs.
The MT8188 SCP requires a main SRAM region and optionally supports an
L1TCM (Level 1 Tightly Coupled Memory) region for performance
optimization. L1TCM is optional because basic SCP functionality works
with only SRAM, but L1TCM provides faster memory access when the board
hardware configuration includes it.
The base schema uses minItems: 1, maxItems: 2 (permissive range),
following the pattern established in other MediaTek dt-bindings like
mediatek,vcodec-encoder.yaml where the base accommodates all variants.
Conditionals then narrow the constraints per device.
Changes in v4:
- Improved commit message clarity per kernel submission guidelines:
* Added bullet-point explanation of the two memory regions
* Explained WHY L1TCM is optional (performance optimization, not
required for basic functionality)
* Explicitly listed which SoCs remain single-region
* Clarified the two-conditional approach
* Explained how minItems: 1 allows board-specific configuration
- Cover letter updated to explain L1TCM optional reasoning
Changes in v3:
- Removed "Tested on..." line (bindings cannot be tested)
- Added minItems: 1 to MT8188 conditional to make L1TCM truly optional
- Referenced mediatek,vcodec-encoder.yaml iommus pattern explicitly
- Base schema: minItems: 1, maxItems: 2 (permissive range)
- Non-MT8188: explicitly restricted to maxItems: 1
- MT8188: documented with item descriptions for both regions
Changes in v2:
- Added conditional schema for MT8188 to allow 1-2 memory regions
- Added descriptions for each memory region
- Did not work: base maxItems: 1 conflicted with conditional
Arnab Layek (1):
dt-bindings: remoteproc: mtk,scp: Allow multiple memory regions for
MT8188
.../bindings/remoteproc/mtk,scp.yaml | 45 ++++++++++++++++++-
1 file changed, 43 insertions(+), 2 deletions(-)
--
2.45.2
^ permalink raw reply
* Re: [PATCH v3 5/5] i2c: mt7621: make device reset optional
From: Benjamin Larsson @ 2026-05-20 9:41 UTC (permalink / raw)
To: Christian Marangi, Stefan Roese, Andi Shyti, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, linux-i2c, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <20260519223253.1093-6-ansuelsmth@gmail.com>
Hi.
On 5/20/26 00:32, Christian Marangi wrote:
> Airoha SoC that makes use of the same Mediatek I2C driver/logic doesn't
> have reset line for I2C so use optional device_reset variant.
>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
> drivers/i2c/busses/i2c-mt7621.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/busses/i2c-mt7621.c b/drivers/i2c/busses/i2c-mt7621.c
> index 3cde43c57a2b..fb9d9701bb10 100644
> --- a/drivers/i2c/busses/i2c-mt7621.c
> +++ b/drivers/i2c/busses/i2c-mt7621.c
> @@ -91,7 +91,7 @@ static void mtk_i2c_reset(struct mtk_i2c *i2c)
> u32 reg;
> int ret;
>
> - ret = device_reset(i2c->adap.dev.parent);
> + ret = device_reset_optional(i2c->adap.dev.parent);
> if (ret)
> dev_err(i2c->dev, "I2C reset failed!\n");
>
Can you elaborate on this one? I get this:
root@XGX-B-00e092000160:~# devmem 0x1fbf8040
0x00C7800C
root@XGX-B-00e092000160:~# devmem 0x1FB00834 32 0x10000
root@XGX-B-00e092000160:~# devmem 0x1fbf8040
[ 396.658742] pbus timeout interrupt ERR ADDR=1fbf8040
[ 396.663845] CPU: 0 PID: 5622 Comm: sleep Tainted: P O 5.4.55 #0
[ 396.671117] Hardware name: XGX-B (DT)
[ 396.674884] Call trace:
[ 396.677394] dump_backtrace+0x0/0x120
[ 396.681111] show_stack+0x14/0x20
[ 396.684478] dump_stack+0xac/0xec
[ 396.687900] bus_timeout_interrupt+0x54/0x70
[ 396.692223] __handle_irq_event_percpu+0x3c/0x140
[ 396.696978] handle_irq_event+0x4c/0xec
[ 396.700920] handle_fasteoi_irq+0xbc/0x21c
[ 396.705069] __handle_domain_irq+0x6c/0xd0
[ 396.709218] gic_handle_irq+0x8c/0x190
[ 396.713019] el1_irq+0xf0/0x1c0
[ 396.716217] __do_softirq+0x98/0x264
[ 396.719847] irq_exit+0x98/0xe0
[ 396.723118] __handle_domain_irq+0x74/0xd0
[ 396.727268] gic_handle_irq+0x8c/0x190
[ 396.731070] el1_irq+0xf0/0x1c0
[ 396.734320] tlb_flush+0xf8/0x260
[ 396.737693] tlb_finish_mmu+0x48/0xe0
[ 396.741417] exit_mmap+0xc0/0x170
[ 396.744841] mmput+0x44/0x120
[ 396.747872] do_exit+0x2b4/0x8ec
[ 396.751161] do_group_exit+0x34/0x9c
[ 396.754794] __wake_up_parent+0x0/0x2c
[ 396.758651] el0_svc_handler+0x8c/0x150
[ 396.762545] el0_svc+0x8/0x208
0xDEADBEEF
root@XGX-B-00e092000160:~# devmem 0x1FB00834 32 0x00000
root@XGX-B-00e092000160:~# devmem 0x1fbf8040
0x0000800C
and
root@XGX-B-00e092000160:~# devmem 0x1fbf8140
0x00318013
root@XGX-B-00e092000160:~# devmem 0x1FB00830 32 0x00040
root@XGX-B-00e092000160:~# devmem 0x1fbf8140
[ 611.730070] pbus timeout interrupt ERR ADDR=1fbf8140
[ 611.735197] CPU: 0 PID: 2651 Comm: ux-manager Tainted: P O
5.4.55 #0
[ 611.742925] Hardware name: XGX-B (DT)
[ 611.746697] Call trace:
[ 611.749222] dump_backtrace+0x0/0x120
[ 611.752960] show_stack+0x14/0x20
[ 611.756424] dump_stack+0xac/0xec
[ 611.759801] bus_timeout_interrupt+0x54/0x70
[ 611.764145] __handle_irq_event_percpu+0x3c/0x140
[ 611.769001] handle_irq_event+0x4c/0xec
[ 611.772912] handle_fasteoi_irq+0xbc/0x21c
[ 611.777077] __handle_domain_irq+0x6c/0xd0
[ 611.781312] gic_handle_irq+0x8c/0x190
[ 611.785117] el1_irq+0xf0/0x1c0
[ 611.788335] __do_softirq+0x98/0x264
[ 611.792032] irq_exit+0x98/0xe0
[ 611.795249] __handle_domain_irq+0x74/0xd0
[ 611.799411] gic_handle_irq+0x8c/0x190
[ 611.803303] el1_irq+0xf0/0x1c0
[ 611.806518] bgpio_read32+0x4/0x20
[ 611.809995] gpiod_get_value_cansleep+0x44/0x100
[ 611.814742] value_show+0x2c/0x64
[ 611.818114] dev_attr_show+0x1c/0x54
[ 611.821760] sysfs_kf_read+0x54/0xc0
[ 611.825396] kernfs_fop_read+0xac/0x300
[ 611.829355] __vfs_read+0x18/0x3c
[ 611.832741] vfs_read+0xc8/0x150
[ 611.836028] ksys_read+0x58/0xd4
[ 611.839369] __arm64_sys_read+0x18/0x20
[ 611.843264] el0_svc_handler+0x8c/0x150
[ 611.847166] el0_svc+0x8/0x208
0xDEADBEEF
root@XGX-B-00e092000160:~# devmem 0x1FB00830 32 0x00000
root@XGX-B-00e092000160:~# devmem 0x1fbf8140
0x00008000
When I look at the current dts:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/airoha/en7581.dtsi?h=v7.1-rc4#n322
it looks like the resets are just crossed with regards to the nodes.
MvH
Benjamin Larsson
^ permalink raw reply
* Re: mt7915e 5GHz/6GHz with multiple cards or dynamic selection - can it be done along these lines?
From: Adam Hill @ 2026-05-20 9:19 UTC (permalink / raw)
To: linux-mediatek
In-Reply-To: <CALgbQMy=XduSht_tq7f7WjsFSos8EX6mSS0pZDGhV3n=OJLy=A@mail.gmail.com>
Since there's been no feedback on this I've created a patch which
allows dynamic switching per card between the 5GHz and 6GHz bands.
This adds a control in sysfs under
/sys/class/ieee80211/phy<x>/controls/use_6ghz if the feature is
supported, set to Y to use 6GHz or N for 5GHz. If the value is
changed, the eeprom capability is re-read using the alternate band and
a full card reset is performed. There are almost certainly better ways
to do this - it would be nice to avoid the reset for example, but it
"works for me" and even seems to work if you switch bands whilst the
radio is active ( if the card is configured for one band and the
channel set is in the other, everything looks ok but the radio won't
be active - switching to the correct band using sysfs causes the card
to reset and the newap appears ). I'm posting this here in case it
helps anyone else - certainly not proposing it goes into the kernel
but I do think someone should look at this and implement it the
"correct" way. One final point is that I added "bool use_6ghz" at line
227 in mt7915.h - it should probably be a bitfield with sku_limit_en
et al but this way the patch applies back to ( at least ) 6.18
kernels. Here's the patch:
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
index eb92cbf1a284..30814469ed5a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
@@ -166,6 +166,9 @@ static void mt7915_eeprom_parse_band_config(struct
mt7915_phy *phy)
val = eeprom[MT_EE_WIFI_CONF + band];
val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
+ if (phy->mt76->cap.has_6ghz && phy->mt76->cap.has_6ghz)
+ val = MT_EE_V2_BAND_SEL_5GHZ_6GHZ;
+
if (!is_mt7915(&dev->mt76)) {
switch (val) {
case MT_EE_V2_BAND_SEL_5GHZ:
@@ -175,13 +178,15 @@ static void
mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
phy->mt76->cap.has_6ghz = true;
return;
case MT_EE_V2_BAND_SEL_5GHZ_6GHZ:
- if (enable_6ghz) {
- phy->mt76->cap.has_6ghz = true;
+ phy->mt76->cap.has_6ghz = true;
+ phy->mt76->cap.has_5ghz = true;
+ if (enable_6ghz || phy->use_6ghz) {
+ dev_info(phy->mt76->dev->dev, "Selecting 6GHz band.\n");
u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band],
MT_EE_V2_BAND_SEL_6GHZ,
MT_EE_WIFI_CONF0_BAND_SEL);
} else {
- phy->mt76->cap.has_5ghz = true;
+ dev_info(phy->mt76->dev->dev, "Selecting 5GHz band.\n");
u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band],
MT_EE_V2_BAND_SEL_5GHZ,
MT_EE_WIFI_CONF0_BAND_SEL);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 250c2d2479b0..d5f5018478d9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -4,6 +4,7 @@
#include <linux/etherdevice.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <linux/sysfs.h>
#include <linux/of.h>
#include <linux/thermal.h>
#include "mt7915.h"
@@ -221,6 +222,70 @@ static int mt7915_thermal_init(struct mt7915_phy *phy)
return PTR_ERR_OR_ZERO(hwmon);
}
+static ssize_t mt7915_sysfs_6ghz_get(struct kobject *kobj, struct
attribute *attr, char *buf)
+{
+ int ret;
+ struct mt7915_phy *phy = container_of(kobj, struct mt7915_phy,
sysfs_controls);
+
+ ret = sysfs_emit(buf, "%c\n", phy->use_6ghz?'Y':'N');
+ return ret;
+}
+
+static ssize_t mt7915_sysfs_6ghz_set(struct kobject *kobj, struct
attribute *attr, const char *buf, size_t count)
+{
+ struct mt7915_phy *phy = container_of(kobj, struct mt7915_phy,
sysfs_controls);
+ bool prev = phy->use_6ghz;
+
+ if (toupper(buf[0]) == 'Y')
+ phy->use_6ghz = true;
+ else
+ phy->use_6ghz = false;
+
+ if (prev != phy->use_6ghz) {
+ mt7915_eeprom_parse_hw_cap(phy->dev, phy);
+ phy->dev->recovery.restart = true;
+ mt7915_reset(phy->dev);
+ //ieee80211_restart_hw(phy->mt76->hw);
+ }
+
+ return count;
+}
+
+static struct sysfs_ops mt7915_sysfs_ops = {
+ .show = mt7915_sysfs_6ghz_get,
+ .store = mt7915_sysfs_6ghz_set
+};
+
+static struct attribute mt7915_sysfs_6ghz = {
+ .name = "use_6ghz",
+ .mode = 0664
+};
+
+static struct attribute *mt7915_sysfs_attrs[] = {
+ &mt7915_sysfs_6ghz,
+ NULL
+};
+
+ATTRIBUTE_GROUPS(mt7915_sysfs);
+
+static const struct kobj_type mt7915_sysfs_ktype = {
+ .sysfs_ops = &mt7915_sysfs_ops,
+ .default_groups = mt7915_sysfs_groups
+};
+
+static int mt7915_sysfs_control_init(struct mt7915_phy *phy)
+{
+ int ret;
+ struct wiphy *wiphy = phy->mt76->hw->wiphy;
+
+ ret = kobject_init_and_add(&phy->sysfs_controls,
&mt7915_sysfs_ktype, &wiphy->dev.kobj, "%s", "controls");
+
+ if (ret)
+ return -ENOMEM;
+
+ return 0;
+}
+
static void mt7915_led_set_config(struct led_classdev *led_cdev,
u8 delay_on, u8 delay_off)
{
@@ -725,6 +790,10 @@ mt7915_register_ext_phy(struct mt7915_dev *dev,
struct mt7915_phy *phy)
if (ret)
goto unreg;
+ ret = mt7915_sysfs_control_init(phy);
+ if (ret)
+ goto unreg;
+
mt7915_init_debugfs(phy);
return 0;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index bf1d915a3ca2..913f8a9d1d30 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -206,6 +206,7 @@ struct mt7915_phy {
struct ieee80211_vif *monitor_vif;
struct thermal_cooling_device *cdev;
+ struct kobject sysfs_controls;
u8 cdev_state;
u8 throttle_state;
u32 throttle_temp[2]; /* 0: critical high, 1: maximum */
@@ -223,6 +224,8 @@ struct mt7915_phy {
u32 rx_ampdu_ts;
u32 ampdu_ref;
+ bool use_6ghz;
+
struct mt76_mib_stats mib;
struct mt76_channel_state state_ts;
On Fri, 15 May 2026 at 18:41, Adam Hill <sidepipeuk@gmail.com> wrote:
>
> Firstly I have to preface this with "I don't know what I'm doing". I
> have almost no knowledge of how these ( or any ) wireless cards
> operate and little knowledge of the inner workings of kernel modules
> etc.... so where I'm going with this might not be possible. I do know
> that the current situation with the mt7915e module isn't ideal.
>
> There are two serious-ish concerns as far as I can see:
>
> 1) It's currently impossible to have multiple 6GHz capable cards in a
> system unless they all operate on either 5GHz or 6GHz, i.e. the same
> band for all cards. This removes the very realistic possibility that
> you might want two cards, one on 5GHz and one on 6GHz.
>
> 2) The band selection is at module load time, and anything looking at
> netlink would be unaware that it's even possible to use the other
> band.
>
> I've been experimenting, and with the patch below ( simply a proof of
> concept ) netlink is supplied with both bands regardless of the one
> selected, and changing /sys/module/mt7915e/parameters/enable_6ghz from
> Y to N or vice versa, followed by assering /sys.../phy<x>/device/reset
> *seems* to allow dynamic switching between bands. However, given my
> aforementioned lack of knowledge, I'm unsure whether what I've done is
> even valid, and if it gets around the original reason for the single
> band selection in the first place ( the original commit, 57af267,
> mentions that memory limitations prevent both bands being configured
> correctly - and I'm not sure if calling mt7915_eeprom_parse_hw_cap is
> sufficient to replace one with theother ). In any case, I can
> successfully switch between bands using this technique ( and also,
> coincidentally, use multiple cards on different bands, but that needs
> a proper solution ).
>
> Ideally, what I *think* should happen, is that rather than a module
> parameter, if a request to set up the band that isn't loaded happens,
> the appropriate steps are taken to reconfigure the hardware to the
> other band. Probably simpler, but also less desirable, would be a
> second module parameter allowing selection on a per-card basis, with a
> callback that performs the reset if it's changed.
>
> My current POC is simply:
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> index eb92cbf1a284..87113459fe30 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> @@ -166,6 +166,9 @@ static void mt7915_eeprom_parse_band_config(struct
> mt7915_phy *phy)
> val = eeprom[MT_EE_WIFI_CONF + band];
> val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
>
> + if (phy->mt76->cap.has_6ghz && phy->mt76->cap.has_6ghz)
> + val = MT_EE_V2_BAND_SEL_5GHZ_6GHZ;
> +
> if (!is_mt7915(&dev->mt76)) {
> switch (val) {
> case MT_EE_V2_BAND_SEL_5GHZ:
> @@ -175,13 +178,13 @@ static void
> mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
> phy->mt76->cap.has_6ghz = true;
> return;
> case MT_EE_V2_BAND_SEL_5GHZ_6GHZ:
> + phy->mt76->cap.has_6ghz = true;
> + phy->mt76->cap.has_5ghz = true;
> if (enable_6ghz) {
> - phy->mt76->cap.has_6ghz = true;
>
> u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band],
> MT_EE_V2_BAND_SEL_6GHZ,
> MT_EE_WIFI_CONF0_BAND_SEL);
> } else {
> - phy->mt76->cap.has_5ghz = true;
>
> u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band],
> MT_EE_V2_BAND_SEL_5GHZ,
> MT_EE_WIFI_CONF0_BAND_SEL);
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> index cec2c4208255..56a8ba648b46 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> @@ -1297,6 +1297,9 @@ mt7915_mac_restart(struct mt7915_dev *dev)
> ext_phy = dev->mt76.phys[MT_BAND1];
> phy2 = ext_phy ? ext_phy->priv : NULL;
>
> + if (phy2)
> + mt7915_eeprom_parse_hw_cap(dev, phy2);
> +
> if (dev->hif2) {
> mt76_wr(dev, MT_INT1_MASK_CSR, 0x0);
> mt76_wr(dev, MT_INT1_SOURCE_CSR, ~0);
^ permalink raw reply related
* [PATCH RFC net-next] net: airoha: Add TCP LRO support
From: Lorenzo Bianconi @ 2026-05-20 8:12 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: linux-arm-kernel, linux-mediatek, netdev, Lorenzo Bianconi
Add hardware TCP Large Receive Offload (LRO) support to the airoha_eth
driver, leveraging the EN7581/AN7583 SoC's 8 dedicated LRO hardware queues
mapped to RX queues 24–31. To meet the hardware requirement for contiguous
memory regions, increase the page_pool allocation order to 2 for RX queues
24–31.
Performance comparison between GRO and hw LRO has been carried out using
a 10Gbps NIC:
GRO: ~2.7 Gbps
LRO: ~3.5 Gbps (~30% improvement)
Please note with respect to the previous implementation, page_pool
allocation order has been reduced from 5 to 2.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 202 +++++++++++++++++++++++++++---
drivers/net/ethernet/airoha/airoha_eth.h | 23 ++++
drivers/net/ethernet/airoha/airoha_regs.h | 22 +++-
3 files changed, 232 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 5a027cc7ffcb..e2c6231ee6a0 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -12,6 +12,7 @@
#include <net/dst_metadata.h>
#include <net/page_pool/helpers.h>
#include <net/pkt_cls.h>
+#include <net/tcp.h>
#include <uapi/linux/ppp_defs.h>
#include "airoha_regs.h"
@@ -431,6 +432,47 @@ static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth)
CDM_CRSN_QSEL_Q1));
}
+static void airoha_fe_lro_init_rx_queue(struct airoha_eth *eth, int qdma_id,
+ int lro_queue_index, int qid,
+ int nbuf, int buf_size)
+{
+ int id = qdma_id + 1;
+
+ airoha_fe_rmw(eth, REG_CDM_LRO_LIMIT(id),
+ CDM_LRO_AGG_NUM_MASK | CDM_LRO_AGG_SIZE_MASK,
+ FIELD_PREP(CDM_LRO_AGG_NUM_MASK, nbuf) |
+ FIELD_PREP(CDM_LRO_AGG_SIZE_MASK, buf_size));
+ airoha_fe_rmw(eth, REG_CDM_LRO_AGE_TIME(id),
+ CDM_LRO_AGE_TIME_MASK | CDM_LRO_AGG_TIME_MASK,
+ FIELD_PREP(CDM_LRO_AGE_TIME_MASK,
+ AIROHA_RXQ_LRO_MAX_AGE_TIME) |
+ FIELD_PREP(CDM_LRO_AGG_TIME_MASK,
+ AIROHA_RXQ_LRO_MAX_AGG_TIME));
+ airoha_fe_rmw(eth, REG_CDM_LRO_RXQ(id, lro_queue_index),
+ LRO_RXQ_MASK(lro_queue_index),
+ __field_prep(LRO_RXQ_MASK(lro_queue_index), qid));
+ airoha_fe_set(eth, REG_CDM_LRO_EN(id), BIT(lro_queue_index));
+}
+
+static void airoha_fe_lro_disable(struct airoha_eth *eth, int qdma_id)
+{
+ int i, id = qdma_id + 1;
+
+ airoha_fe_clear(eth, REG_CDM_LRO_LIMIT(id),
+ CDM_LRO_AGG_NUM_MASK | CDM_LRO_AGG_SIZE_MASK);
+ airoha_fe_clear(eth, REG_CDM_LRO_AGE_TIME(id),
+ CDM_LRO_AGE_TIME_MASK | CDM_LRO_AGG_TIME_MASK);
+ airoha_fe_clear(eth, REG_CDM_LRO_EN(id), LRO_RXQ_EN_MASK);
+ for (i = 0; i < AIROHA_MAX_NUM_LRO_QUEUES; i++)
+ airoha_fe_clear(eth, REG_CDM_LRO_RXQ(id, i), LRO_RXQ_MASK(i));
+}
+
+static bool airoha_fe_lro_is_enabled(struct airoha_eth *eth, int qdma_id)
+{
+ return airoha_fe_get(eth, REG_CDM_LRO_EN(qdma_id + 1),
+ LRO_RXQ_EN_MASK);
+}
+
static int airoha_fe_init(struct airoha_eth *eth)
{
airoha_fe_maccr_init(eth);
@@ -587,9 +629,78 @@ static int airoha_qdma_get_gdm_port(struct airoha_eth *eth,
return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port;
}
+static int airoha_qdma_lro_rx_process(struct airoha_queue *q,
+ struct airoha_qdma_desc *desc)
+{
+ u32 msg1 = le32_to_cpu(READ_ONCE(desc->msg1));
+ u32 msg2 = le32_to_cpu(READ_ONCE(desc->msg2));
+ u32 msg3 = le32_to_cpu(READ_ONCE(desc->msg3));
+ bool ipv4 = FIELD_GET(QDMA_ETH_RXMSG_IP4_MASK, msg1);
+ bool ipv6 = FIELD_GET(QDMA_ETH_RXMSG_IP6_MASK, msg1);
+ struct sk_buff *skb = q->skb;
+ u32 th_off, tcp_ack_seq;
+ u16 tcp_win, l2_len;
+ struct tcphdr *th;
+
+ if (FIELD_GET(QDMA_ETH_RXMSG_AGG_COUNT_MASK, msg2) <= 1)
+ return 0;
+
+ if (!ipv4 && !ipv6)
+ return -EOPNOTSUPP;
+
+ l2_len = FIELD_GET(QDMA_ETH_RXMSG_L2_LEN_MASK, msg2);
+ if (ipv4) {
+ u16 agg_len = FIELD_GET(QDMA_ETH_RXMSG_AGG_LEN_MASK, msg3);
+ struct iphdr *iph = (struct iphdr *)(skb->data + l2_len);
+
+ if (iph->protocol != IPPROTO_TCP)
+ return -EOPNOTSUPP;
+
+ iph->tot_len = cpu_to_be16(agg_len);
+ iph->check = 0;
+ iph->check = ip_fast_csum((void *)iph, iph->ihl);
+ th_off = l2_len + (iph->ihl << 2);
+ } else {
+ struct ipv6hdr *ip6h = (struct ipv6hdr *)(skb->data + l2_len);
+ u32 len, desc_ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
+
+ if (ip6h->nexthdr != NEXTHDR_TCP)
+ return -EOPNOTSUPP;
+
+ len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl);
+ ip6h->payload_len = cpu_to_be16(len - l2_len - sizeof(*ip6h));
+ th_off = l2_len + sizeof(*ip6h);
+ }
+
+ tcp_win = FIELD_GET(QDMA_ETH_RXMSG_TCP_WIN_MASK, msg3);
+ tcp_ack_seq = le32_to_cpu(READ_ONCE(desc->data));
+
+ th = (struct tcphdr *)(skb->data + th_off);
+ th->ack_seq = cpu_to_be32(tcp_ack_seq);
+ th->window = cpu_to_be16(tcp_win);
+
+ /* Check tcp timestamp option */
+ if (th->doff == (sizeof(*th) + TCPOLEN_TSTAMP_ALIGNED) / 4) {
+ __be32 *topt = (__be32 *)(th + 1);
+
+ if (*topt == cpu_to_be32((TCPOPT_NOP << 24) |
+ (TCPOPT_NOP << 16) |
+ (TCPOPT_TIMESTAMP << 8) |
+ TCPOLEN_TIMESTAMP)) {
+ __le32 tcp_ts_reply = READ_ONCE(desc->tcp_ts_reply);
+
+ put_unaligned_be32(le32_to_cpu(tcp_ts_reply),
+ topt + 2);
+ }
+ }
+
+ return 0;
+}
+
static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
{
enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
+ bool lro_q = airoha_qdma_is_lro_queue(q);
struct airoha_qdma *qdma = q->qdma;
struct airoha_eth *eth = qdma->eth;
int qid = q - &qdma->q_rx[0];
@@ -636,9 +747,14 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
__skb_put(q->skb, len);
skb_mark_for_recycle(q->skb);
q->skb->dev = port->dev;
- q->skb->protocol = eth_type_trans(q->skb, port->dev);
q->skb->ip_summed = CHECKSUM_UNNECESSARY;
skb_record_rx_queue(q->skb, qid);
+
+ if (lro_q && (port->dev->features & NETIF_F_LRO) &&
+ airoha_qdma_lro_rx_process(q, desc) < 0)
+ goto free_frag;
+
+ q->skb->protocol = eth_type_trans(q->skb, port->dev);
} else { /* scattered frame */
struct skb_shared_info *shinfo = skb_shinfo(q->skb);
int nr_frags = shinfo->nr_frags;
@@ -727,23 +843,19 @@ static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget)
static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
struct airoha_qdma *qdma, int ndesc)
{
- const struct page_pool_params pp_params = {
- .order = 0,
- .pool_size = 256,
+ struct page_pool_params pp_params = {
.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
.dma_dir = DMA_FROM_DEVICE,
- .max_len = PAGE_SIZE,
.nid = NUMA_NO_NODE,
.dev = qdma->eth->dev,
.napi = &q->napi,
};
+ int pp_order, qid = q - &qdma->q_rx[0], thr;
struct airoha_eth *eth = qdma->eth;
- int qid = q - &qdma->q_rx[0], thr;
dma_addr_t dma_addr;
+ bool lro_q;
- q->buf_size = PAGE_SIZE / 2;
q->qdma = qdma;
-
q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry),
GFP_KERNEL);
if (!q->entry)
@@ -754,6 +866,12 @@ static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
if (!q->desc)
return -ENOMEM;
+ lro_q = airoha_qdma_is_lro_queue(q);
+ pp_order = lro_q ? AIROHA_LRO_PAGE_ORDER : 0;
+ pp_params.order = pp_order;
+ pp_params.pool_size = 256 >> pp_order;
+ pp_params.max_len = PAGE_SIZE << pp_order;
+
q->page_pool = page_pool_create(&pp_params);
if (IS_ERR(q->page_pool)) {
int err = PTR_ERR(q->page_pool);
@@ -762,6 +880,7 @@ static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
return err;
}
+ q->buf_size = pp_params.max_len / (2 * (1 + lro_q));
q->ndesc = ndesc;
netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
@@ -1991,6 +2110,63 @@ int airoha_get_fe_port(struct airoha_gdm_port *port)
}
}
+static int airoha_dev_set_features(struct net_device *dev,
+ netdev_features_t features)
+{
+ netdev_features_t diff = dev->features ^ features;
+ struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_qdma *qdma = port->qdma;
+ struct airoha_eth *eth = qdma->eth;
+ int qdma_id = qdma - ð->qdma[0];
+ int i;
+
+ if (!(diff & NETIF_F_LRO))
+ return 0;
+
+ /* reset LRO configuration */
+ if (features & NETIF_F_LRO) {
+ int lro_queue_index = 0;
+
+ if (airoha_fe_lro_is_enabled(eth, qdma_id))
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
+ struct airoha_queue *q = &qdma->q_rx[i];
+
+ if (!q->ndesc)
+ continue;
+
+ if (!airoha_qdma_is_lro_queue(q))
+ continue;
+
+ airoha_fe_lro_init_rx_queue(eth, qdma_id,
+ lro_queue_index, i,
+ q->page_pool->p.pool_size,
+ q->buf_size);
+ lro_queue_index++;
+ }
+ } else {
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
+ struct airoha_gdm_port *p = eth->ports[i];
+
+ if (!p)
+ continue;
+
+ if (p->qdma != qdma)
+ continue;
+
+ if (p->dev == dev)
+ continue;
+
+ if (p->dev->features & NETIF_F_LRO)
+ return 0;
+ }
+ airoha_fe_lro_disable(eth, qdma_id);
+ }
+
+ return 0;
+}
+
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct net_device *dev)
{
@@ -2890,6 +3066,7 @@ static const struct net_device_ops airoha_netdev_ops = {
.ndo_stop = airoha_dev_stop,
.ndo_change_mtu = airoha_dev_change_mtu,
.ndo_select_queue = airoha_dev_select_queue,
+ .ndo_set_features = airoha_dev_set_features,
.ndo_start_xmit = airoha_dev_xmit,
.ndo_get_stats64 = airoha_dev_get_stats64,
.ndo_set_mac_address = airoha_dev_set_macaddr,
@@ -2987,12 +3164,9 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
dev->ethtool_ops = &airoha_ethtool_ops;
dev->max_mtu = AIROHA_MAX_MTU;
dev->watchdog_timeo = 5 * HZ;
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
- NETIF_F_TSO6 | NETIF_F_IPV6_CSUM |
- NETIF_F_SG | NETIF_F_TSO |
- NETIF_F_HW_TC;
- dev->features |= dev->hw_features;
- dev->vlan_features = dev->hw_features;
+ dev->hw_features = AIROHA_HW_FEATURES | NETIF_F_LRO;
+ dev->features |= AIROHA_HW_FEATURES;
+ dev->vlan_features = AIROHA_HW_FEATURES;
dev->dev.of_node = np;
SET_NETDEV_DEV(dev, eth->dev);
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index d3781103abb5..39ab6bdb1f67 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -43,6 +43,17 @@
(_n) == 15 ? 128 : \
(_n) == 0 ? 1024 : 16)
+#define AIROHA_LRO_PAGE_ORDER 2
+#define AIROHA_MAX_NUM_LRO_QUEUES 8
+#define AIROHA_RXQ_LRO_EN_MASK 0xff000000
+#define AIROHA_RXQ_LRO_MAX_AGG_TIME 100
+#define AIROHA_RXQ_LRO_MAX_AGE_TIME 2000 /* 1ms */
+
+#define AIROHA_HW_FEATURES \
+ (NETIF_F_IP_CSUM | NETIF_F_RXCSUM | \
+ NETIF_F_TSO6 | NETIF_F_IPV6_CSUM | \
+ NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_TC)
+
#define PSE_RSV_PAGES 128
#define PSE_QUEUE_RSV_PAGES 64
@@ -661,6 +672,18 @@ static inline bool airoha_is_7583(struct airoha_eth *eth)
return eth->soc->version == 0x7583;
}
+static inline bool airoha_qdma_is_lro_queue(struct airoha_queue *q)
+{
+ struct airoha_qdma *qdma = q->qdma;
+ int qid = q - &qdma->q_rx[0];
+
+ /* EN7581 SoC supports at most 8 LRO rx queues */
+ BUILD_BUG_ON(hweight32(AIROHA_RXQ_LRO_EN_MASK) >
+ AIROHA_MAX_NUM_LRO_QUEUES);
+
+ return !!(AIROHA_RXQ_LRO_EN_MASK & BIT(qid));
+}
+
int airoha_get_fe_port(struct airoha_gdm_port *port);
bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
struct airoha_gdm_port *port);
diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h
index 436f3c8779c1..dfc786583774 100644
--- a/drivers/net/ethernet/airoha/airoha_regs.h
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
@@ -122,6 +122,20 @@
#define CDM_CRSN_QSEL_REASON_MASK(_n) \
GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3))
+#define REG_CDM_LRO_RXQ(_n, _m) (CDM_BASE(_n) + 0x78 + ((_m) & 0x4))
+#define LRO_RXQ_MASK(_n) GENMASK(4 + (((_n) & 0x3) << 3), ((_n) & 0x3) << 3)
+
+#define REG_CDM_LRO_EN(_n) (CDM_BASE(_n) + 0x80)
+#define LRO_RXQ_EN_MASK GENMASK(7, 0)
+
+#define REG_CDM_LRO_LIMIT(_n) (CDM_BASE(_n) + 0x84)
+#define CDM_LRO_AGG_NUM_MASK GENMASK(23, 16)
+#define CDM_LRO_AGG_SIZE_MASK GENMASK(15, 0)
+
+#define REG_CDM_LRO_AGE_TIME(_n) (CDM_BASE(_n) + 0x88)
+#define CDM_LRO_AGE_TIME_MASK GENMASK(31, 16)
+#define CDM_LRO_AGG_TIME_MASK GENMASK(15, 0)
+
#define REG_GDM_FWD_CFG(_n) GDM_BASE(_n)
#define GDM_PAD_EN_MASK BIT(28)
#define GDM_DROP_CRC_ERR_MASK BIT(23)
@@ -883,9 +897,15 @@
#define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21)
#define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16)
#define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0)
+/* RX MSG2 */
+#define QDMA_ETH_RXMSG_AGG_COUNT_MASK GENMASK(31, 24)
+#define QDMA_ETH_RXMSG_L2_LEN_MASK GENMASK(6, 0)
+/* RX MSG3 */
+#define QDMA_ETH_RXMSG_AGG_LEN_MASK GENMASK(31, 16)
+#define QDMA_ETH_RXMSG_TCP_WIN_MASK GENMASK(15, 0)
struct airoha_qdma_desc {
- __le32 rsv;
+ __le32 tcp_ts_reply;
__le32 ctrl;
__le32 addr;
__le32 data;
---
base-commit: bf53bf33206137c2337bd8aacf0ef4c348b97a36
change-id: 20260520-airoha-eth-lro-a5d1c3631811
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related
* [PATCH] Bluetooth: btmtk: remove extra copy in cmd array init
From: Jiajia Liu @ 2026-05-20 2:15 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
AngeloGioacchino Del Regno
Cc: linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
Jiajia Liu
In btmtk_setup_firmware_79xx, the data length indicated by wmt_params.dlen
in the cmd buffer is MTK_SEC_MAP_NEED_SEND_SIZE + 1. Except for the first
byte, the remaining length is MTK_SEC_MAP_NEED_SEND_SIZE. memcpy copied one
more byte to cmd + 1 than the remaining length. Align the length passed to
memcpy to avoid exceeding current section map.
Signed-off-by: Jiajia Liu <liujiajia@kylinos.cn>
---
drivers/bluetooth/btmtk.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index ea7a031000cd..53cba71cb07f 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -188,7 +188,7 @@ int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
MTK_FW_ROM_PATCH_GD_SIZE +
MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i +
MTK_SEC_MAP_COMMON_SIZE,
- MTK_SEC_MAP_NEED_SEND_SIZE + 1);
+ MTK_SEC_MAP_NEED_SEND_SIZE);
wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
wmt_params.status = &status;
--
2.53.0
^ permalink raw reply related
* [PATCH v3 5/5] i2c: mt7621: make device reset optional
From: Christian Marangi @ 2026-05-19 22:32 UTC (permalink / raw)
To: Stefan Roese, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
linux-i2c, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
Cc: Christian Marangi
In-Reply-To: <20260519223253.1093-1-ansuelsmth@gmail.com>
Airoha SoC that makes use of the same Mediatek I2C driver/logic doesn't
have reset line for I2C so use optional device_reset variant.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/i2c/busses/i2c-mt7621.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-mt7621.c b/drivers/i2c/busses/i2c-mt7621.c
index 3cde43c57a2b..fb9d9701bb10 100644
--- a/drivers/i2c/busses/i2c-mt7621.c
+++ b/drivers/i2c/busses/i2c-mt7621.c
@@ -91,7 +91,7 @@ static void mtk_i2c_reset(struct mtk_i2c *i2c)
u32 reg;
int ret;
- ret = device_reset(i2c->adap.dev.parent);
+ ret = device_reset_optional(i2c->adap.dev.parent);
if (ret)
dev_err(i2c->dev, "I2C reset failed!\n");
--
2.53.0
^ permalink raw reply related
* [PATCH v3 3/5] dt-bindings: i2c: mt7621: Document an7581 compatible
From: Christian Marangi @ 2026-05-19 22:32 UTC (permalink / raw)
To: Stefan Roese, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
linux-i2c, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
Cc: Christian Marangi
In-Reply-To: <20260519223253.1093-1-ansuelsmth@gmail.com>
Airoha SoC implement the same Mediatek logic for I2C bus with the only
difference of not having a dedicated reset line to reset it.
Add a dedicated compatible for the Airoha AN7581 SoC and reject the
unsupported property.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
.../bindings/i2c/mediatek,mt7621-i2c.yaml | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/i2c/mediatek,mt7621-i2c.yaml b/Documentation/devicetree/bindings/i2c/mediatek,mt7621-i2c.yaml
index 118ec00fc190..8223fbc74f14 100644
--- a/Documentation/devicetree/bindings/i2c/mediatek,mt7621-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/mediatek,mt7621-i2c.yaml
@@ -14,7 +14,9 @@ allOf:
properties:
compatible:
- const: mediatek,mt7621-i2c
+ enum:
+ - airoha,an7581-i2c
+ - mediatek,mt7621-i2c
reg:
maxItems: 1
@@ -38,6 +40,16 @@ required:
- "#address-cells"
- "#size-cells"
+if:
+ properties:
+ compatible:
+ contains:
+ const: airoha,an7581-i2c
+then:
+ properties:
+ resets: false
+ reset-names: false
+
unevaluatedProperties: false
examples:
--
2.53.0
^ permalink raw reply related
* [PATCH v3 4/5] i2c: mt7621: limit SCL_STRETCH only to Mediatek SoC
From: Christian Marangi @ 2026-05-19 22:32 UTC (permalink / raw)
To: Stefan Roese, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
linux-i2c, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
Cc: Christian Marangi
In-Reply-To: <20260519223253.1093-1-ansuelsmth@gmail.com>
The same I2C driver is also used for Airoha SoC with the only difference
that the i2c_reset should not enable SCL_STRETCH for Airoha SoC.
Introduce a new compatible for Airoha and limit the SCL_STRETCH only to
mediatek SoC.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/i2c/busses/i2c-mt7621.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mt7621.c b/drivers/i2c/busses/i2c-mt7621.c
index d8fa29e7e0fa..3cde43c57a2b 100644
--- a/drivers/i2c/busses/i2c-mt7621.c
+++ b/drivers/i2c/busses/i2c-mt7621.c
@@ -88,6 +88,7 @@ static int mtk_i2c_wait_idle(struct mtk_i2c *i2c, bool atomic)
static void mtk_i2c_reset(struct mtk_i2c *i2c)
{
+ u32 reg;
int ret;
ret = device_reset(i2c->adap.dev.parent);
@@ -98,8 +99,12 @@ static void mtk_i2c_reset(struct mtk_i2c *i2c)
* Don't set SM0CTL0_ODRAIN as its bit meaning is inverted. To
* configure open-drain mode, this bit needs to be cleared.
*/
- iowrite32(((i2c->clk_div << 16) & SM0CTL0_CLK_DIV_MASK) | SM0CTL0_EN |
- SM0CTL0_SCL_STRETCH, i2c->base + REG_SM0CTL0_REG);
+ reg = ((i2c->clk_div << 16) & SM0CTL0_CLK_DIV_MASK) | SM0CTL0_EN;
+ /* Set SCL_STRETCH only for Mediatek SoC */
+ if (device_is_compatible(i2c->dev, "mediatek,mt7621-i2c"))
+ reg |= SM0CTL0_SCL_STRETCH;
+
+ iowrite32(reg, i2c->base + REG_SM0CTL0_REG);
iowrite32(0, i2c->base + REG_SM0CFG2_REG);
/* Clear any pending interrupt */
iowrite32(1, i2c->base + REG_PINTEN_REG);
@@ -271,6 +276,7 @@ static const struct i2c_algorithm mtk_i2c_algo = {
static const struct of_device_id i2c_mtk_dt_ids[] = {
{ .compatible = "mediatek,mt7621-i2c" },
+ { .compatible = "airoha,an7581-i2c" },
{ /* sentinel */ }
};
--
2.53.0
^ permalink raw reply related
* [PATCH v3 2/5] i2c: mt7621: clear pending interrupt on i2c reset
From: Christian Marangi @ 2026-05-19 22:32 UTC (permalink / raw)
To: Stefan Roese, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
linux-i2c, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
Cc: Christian Marangi
In-Reply-To: <20260519223253.1093-1-ansuelsmth@gmail.com>
On resetting the i2c bus, clear any pending interrupt to have a more
consistent state on the next operation.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/i2c/busses/i2c-mt7621.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/i2c/busses/i2c-mt7621.c b/drivers/i2c/busses/i2c-mt7621.c
index 700beb9e7b1a..d8fa29e7e0fa 100644
--- a/drivers/i2c/busses/i2c-mt7621.c
+++ b/drivers/i2c/busses/i2c-mt7621.c
@@ -101,6 +101,8 @@ static void mtk_i2c_reset(struct mtk_i2c *i2c)
iowrite32(((i2c->clk_div << 16) & SM0CTL0_CLK_DIV_MASK) | SM0CTL0_EN |
SM0CTL0_SCL_STRETCH, i2c->base + REG_SM0CTL0_REG);
iowrite32(0, i2c->base + REG_SM0CFG2_REG);
+ /* Clear any pending interrupt */
+ iowrite32(1, i2c->base + REG_PINTEN_REG);
}
static void mtk_i2c_dump_reg(struct mtk_i2c *i2c)
--
2.53.0
^ permalink raw reply related
* [PATCH v3 1/5] i2c: mt7621: rework cmd/wait OPs to support atomic afer variant
From: Christian Marangi @ 2026-05-19 22:32 UTC (permalink / raw)
To: Stefan Roese, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
linux-i2c, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
Cc: Christian Marangi
In-Reply-To: <20260519223253.1093-1-ansuelsmth@gmail.com>
It was reported the need for atomic operation on some Airoha SoC that
makes use of I2C bus. Rework the cmd/wait OPs to suppor the xfer_atomic
variant. To support this it's mainlin needed to do the readl poll in
atomic context.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/i2c/busses/i2c-mt7621.c | 56 ++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 18 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mt7621.c b/drivers/i2c/busses/i2c-mt7621.c
index 0a288c998419..700beb9e7b1a 100644
--- a/drivers/i2c/busses/i2c-mt7621.c
+++ b/drivers/i2c/busses/i2c-mt7621.c
@@ -67,14 +67,19 @@ struct mtk_i2c {
struct clk *clk;
};
-static int mtk_i2c_wait_idle(struct mtk_i2c *i2c)
+static int mtk_i2c_wait_idle(struct mtk_i2c *i2c, bool atomic)
{
int ret;
u32 val;
- ret = readl_relaxed_poll_timeout(i2c->base + REG_SM0CTL1_REG,
- val, !(val & SM0CTL1_TRI),
- 10, TIMEOUT_MS * 1000);
+ if (atomic)
+ ret = readl_relaxed_poll_timeout_atomic(i2c->base + REG_SM0CTL1_REG,
+ val, !(val & SM0CTL1_TRI),
+ 10, TIMEOUT_MS * 1000);
+ else
+ ret = readl_relaxed_poll_timeout(i2c->base + REG_SM0CTL1_REG,
+ val, !(val & SM0CTL1_TRI),
+ 10, TIMEOUT_MS * 1000);
if (ret)
dev_dbg(i2c->dev, "idle err(%d)\n", ret);
@@ -117,27 +122,28 @@ static int mtk_i2c_check_ack(struct mtk_i2c *i2c, u32 expected)
return ((ack & ack_expected) == ack_expected) ? 0 : -ENXIO;
}
-static int mtk_i2c_start(struct mtk_i2c *i2c)
+static int mtk_i2c_start(struct mtk_i2c *i2c, bool atomic)
{
iowrite32(SM0CTL1_START | SM0CTL1_TRI, i2c->base + REG_SM0CTL1_REG);
- return mtk_i2c_wait_idle(i2c);
+ return mtk_i2c_wait_idle(i2c, atomic);
}
-static int mtk_i2c_stop(struct mtk_i2c *i2c)
+static int mtk_i2c_stop(struct mtk_i2c *i2c, bool atomic)
{
iowrite32(SM0CTL1_STOP | SM0CTL1_TRI, i2c->base + REG_SM0CTL1_REG);
- return mtk_i2c_wait_idle(i2c);
+ return mtk_i2c_wait_idle(i2c, atomic);
}
-static int mtk_i2c_cmd(struct mtk_i2c *i2c, u32 cmd, int page_len)
+static int mtk_i2c_cmd(struct mtk_i2c *i2c, u32 cmd, int page_len,
+ bool atomic)
{
iowrite32(cmd | SM0CTL1_TRI | SM0CTL1_PGLEN(page_len),
i2c->base + REG_SM0CTL1_REG);
- return mtk_i2c_wait_idle(i2c);
+ return mtk_i2c_wait_idle(i2c, atomic);
}
-static int mtk_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
- int num)
+static int mtk_i2c_xfer_common(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num, bool atomic)
{
struct mtk_i2c *i2c;
struct i2c_msg *pmsg;
@@ -152,12 +158,12 @@ static int mtk_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
pmsg = &msgs[i];
/* wait hardware idle */
- ret = mtk_i2c_wait_idle(i2c);
+ ret = mtk_i2c_wait_idle(i2c, atomic);
if (ret)
goto err_timeout;
/* start sequence */
- ret = mtk_i2c_start(i2c);
+ ret = mtk_i2c_start(i2c, atomic);
if (ret)
goto err_timeout;
@@ -173,7 +179,8 @@ static int mtk_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
len = 1;
}
iowrite32(addr, i2c->base + REG_SM0D0_REG);
- ret = mtk_i2c_cmd(i2c, SM0CTL1_WRITE, len);
+ ret = mtk_i2c_cmd(i2c, SM0CTL1_WRITE, len,
+ atomic);
if (ret)
goto err_timeout;
@@ -198,7 +205,7 @@ static int mtk_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
cmd = SM0CTL1_WRITE;
}
- ret = mtk_i2c_cmd(i2c, cmd, page_len);
+ ret = mtk_i2c_cmd(i2c, cmd, page_len, atomic);
if (ret)
goto err_timeout;
@@ -218,7 +225,7 @@ static int mtk_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
}
}
- ret = mtk_i2c_stop(i2c);
+ ret = mtk_i2c_stop(i2c, atomic);
if (ret)
goto err_timeout;
@@ -226,7 +233,7 @@ static int mtk_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
return i;
err_ack:
- ret = mtk_i2c_stop(i2c);
+ ret = mtk_i2c_stop(i2c, atomic);
if (ret)
goto err_timeout;
return -ENXIO;
@@ -237,6 +244,18 @@ static int mtk_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
return ret;
}
+static int mtk_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
+{
+ return mtk_i2c_xfer_common(adap, msgs, num, false);
+}
+
+static int mtk_i2c_xfer_atomic(struct i2c_adapter *adap,
+ struct i2c_msg *msgs, int num)
+{
+ return mtk_i2c_xfer_common(adap, msgs, num, true);
+}
+
static u32 mtk_i2c_func(struct i2c_adapter *a)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
@@ -244,6 +263,7 @@ static u32 mtk_i2c_func(struct i2c_adapter *a)
static const struct i2c_algorithm mtk_i2c_algo = {
.xfer = mtk_i2c_xfer,
+ .xfer_atomic = mtk_i2c_xfer_atomic,
.functionality = mtk_i2c_func,
};
--
2.53.0
^ permalink raw reply related
* [PATCH v3 0/5] i2c: mt7621: improve support for Airoha
From: Christian Marangi @ 2026-05-19 22:32 UTC (permalink / raw)
To: Stefan Roese, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
linux-i2c, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
Cc: Christian Marangi
This small series improve support for Airoha SoC that use the
same MT7621 implementation. Some additional tweak are required
to better support it.
Also we add support for atomic variant of .xfer required for
some attached pheriperals on the Airoha SoC.
Changes v3:
- Rebase on top of linux-next
Changes v2:
- Fix compatible order for schema patch
Christian Marangi (5):
i2c: mt7621: rework cmd/wait OPs to support atomic afer variant
i2c: mt7621: clear pending interrupt on i2c reset
dt-bindings: i2c: mt7621: Document an7581 compatible
i2c: mt7621: limit SCL_STRETCH only to Mediatek SoC
i2c: mt7621: make device reset optional
Christian Marangi (5):
i2c: mt7621: rework cmd/wait OPs to support atomic afer variant
i2c: mt7621: clear pending interrupt on i2c reset
dt-bindings: i2c: mt7621: Document an7581 compatible
i2c: mt7621: limit SCL_STRETCH only to Mediatek SoC
i2c: mt7621: make device reset optional
.../bindings/i2c/mediatek,mt7621-i2c.yaml | 14 +++-
drivers/i2c/busses/i2c-mt7621.c | 70 +++++++++++++------
2 files changed, 62 insertions(+), 22 deletions(-)
--
2.53.0
^ permalink raw reply
* Re: [PATCH] ASoC: mediatek: mt2701: fix snprintf bounds
From: Rosen Penev @ 2026-05-19 21:57 UTC (permalink / raw)
To: Mark Brown
Cc: linux-sound, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Matthias Brugger, AngeloGioacchino Del Regno,
open list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support
In-Reply-To: <61fa661f-0281-4b58-8042-f3f60cdc3407@sirena.org.uk>
On Tue, May 19, 2026 at 1:33 AM Mark Brown <broonie@kernel.org> wrote:
>
> On Mon, May 18, 2026 at 06:04:40PM -0700, Rosen Penev wrote:
> > For whatever reason, GCC is unable to figure out that i2s_num is a
> > single digit number, with MT2701_BASE_CLK_NUM being the maximum value it
> > represents. Add a min() call to help it out and fix W=1 errors regarding
> > snprintf bounds.
>
> > + i2s_num = min(MT2701_BASE_CLK_NUM, afe_priv->soc->i2s_num);
> > /* Get I2S related clocks */
> > - for (i = 0; i < afe_priv->soc->i2s_num; i++) {
> > + for (i = 0; i < i2s_num; i++) {
>
> This makes the code rather obscure and will start silently failing if we
> ever get more than 9 clocks, we should at least put a build time assert
> or a warn on in there.
how so? MT2701_BASE_CLK_NUM would increase.
^ permalink raw reply
* Re: [PATCH] wifi: mt76: mt7996: avoid memset overwriting tx_info->control.flags
From: Ryder Lee @ 2026-05-19 20:42 UTC (permalink / raw)
To: lorenzo.bianconi83@gmail.com, roychl666@gmail.com
Cc: linux-wireless@vger.kernel.org, nbd@nbd.name, lorenzo@kernel.org,
Shayne Chen (陳軒丞),
linux-mediatek@lists.infradead.org, Roy-CH Luo
In-Reply-To: <CAA2SeNJXv+8QO6zEOF=qB3wVCdEoSqx6fftp1i=aB-DKMFeC=A@mail.gmail.com>
On Tue, 2026-05-19 at 14:24 +0200, Lorenzo Bianconi wrote:
>
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> >
> > On Mon, May 18, 2026 at 5:31 AM Lorenzo Bianconi
> > <lorenzo@kernel.org> wrote:
> > >
> > > On May 15, Cheng Hao Luo wrote:
> > > > > struct ieee80211_tx_info {
> > > > > u32 flags;
> > > > > /* 0 4 */
> > > > > u32 band:3;
> > > > > /* 4: 0 4 */
> > > > > u32 status_data_idr:1;
> > > > > /* 4: 3 4 */
> > > > > u32 status_data:13;
> > > > > /* 4: 4 4 */
> > > > > u32 hw_queue:4;
> > > > > /* 4:17 4 */
> > > > > u32 tx_time_est:10;
> > > > > /* 4:21 4 */
> > > > >
> > > > > /* XXX 1 bit hole, try to pack */
> > > > >
> > > > > union {
> > > > > struct {
> > > > > union {
> > > > > struct {
> > > > > struct
> > > > > ieee80211_tx_rate rates[4]; /* 8 12 */
> > > > > s8
> > > > > rts_cts_rate_idx; /* 20 1 */
> > > > > u8 use_rts:1;
> > > > > /* 21: 0 1 */
> > > > > u8
> > > > > use_cts_prot:1; /* 21: 1 1 */
> > > > > u8
> > > > > short_preamble:1; /* 21: 2 1 */
> > > > > u8 skip_table:1;
> > > > > /* 21: 3 1 */
> > > > > u8 antennas:2;
> > > > > /* 21: 4 1 */
> > > > > };
> > > > > /* 8 14 */
> > > > > long unsigned int jiffies;
> > > > > /* 8 8 */
> > > > > };
> > > > > /* 8 16 */
> > > > > struct ieee80211_vif * vif;
> > > > > /* 24 8 */
> > > > > struct ieee80211_key_conf * hw_key;
> > > > > /* 32 8 */
> > > > > u32 flags;
> > > > > /* 40 4 */
> > > > > codel_time_t enqueue_time;
> > > > > /* 44 4 */
> > > > > } control;
> > > > > /* 8 40 */
> > > > > struct {
> > > > > u64 cookie;
> > > > > /* 8 8 */
> > > > > } ack;
> > > > > /* 8 8 */
> > > > > struct {
> > > > > struct ieee80211_tx_rate rates[4];
> > > > > /* 8 12 */
> > > > > s32 ack_signal;
> > > > > /* 20 4 */
> > > > > u8 ampdu_ack_len;
> > > > > /* 24 1 */
> > > > > u8 ampdu_len;
> > > > > /* 25 1 */
> > > > > u8 antenna;
> > > > > /* 26 1 */
> > > > > u8 pad;
> > > > > /* 27 1 */
> > > > > u16 tx_time;
> > > > > /* 28 2 */
> > > > > u8 flags;
> > > > > /* 30 1 */
> > > > > u8 pad2;
> > > > > /* 31 1 */
> > > > > void * status_driver_data[2];
> > > > > /* 32 16 */
> > > > > } status;
> > > > > /* 8 40 */
> > > > > struct {
> > > > > struct ieee80211_tx_rate
> > > > > driver_rates[4]; /* 8 12 */
> > > > > u8 pad[4];
> > > > > /* 20 4 */
> > > > > void * rate_driver_data[3];
> > > > > /* 24 24 */
> > > > > };
> > > > > /* 8 40 */
> > > > > void * driver_data[5];
> > > > > /* 8 40 */
> > > > > };
> > > > > /* 8 40 */
> > > > >
> > > > > /* size: 48, cachelines: 1, members: 7 */
> > > > > /* sum members: 44 */
> > > > > /* sum bitfield members: 31 bits, bit holes: 1, sum
> > > > > bit holes: 1 bits */
> > > > > /* last cacheline: 48 bytes */
> > > > > };
> > > > >
> > > > > According to pahole, the size of the control inner union is
> > > > > actually 16 bytes
> > > > > since the compiler adds 2 bytes of padding. Since
> > > > > mt76_tx_status_skb_add()
> > > > > meset to 0 just mt76_tx_cb size (that is 16 bytes) I can't
> > > > > see how
> > > > > control.flags is overwritten. Am I missing something?
> > > > >
> > > > > struct mt76_tx_cb {
> > > > > long unsigned int jiffies;
> > > > > /* 0 8 */
> > > > > u16 wcid;
> > > > > /* 8 2 */
> > > > > u8 pktid;
> > > > > /* 10 1 */
> > > > > u8 flags;
> > > > > /* 11 1 */
> > > > >
> > > > > /* size: 16, cachelines: 1, members: 4 */
> > > > > /* padding: 4 */
> > > > > /* last cacheline: 16 bytes */
> > > > > };
> > > >
> > > > Hi Lorenzo,
> > > >
> > > > The mt76_tx_cb is placed at status.status_driver_data (offset
> > > > 32).
> > > > It overlaps with hw_key, flags and enqueue_time in the control
> > > > union.
> > > >
> > > > static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff
> > > > *skb)
> > > > {
> > > > BUILD_BUG_ON(sizeof(struct mt76_tx_cb) >
> > > > sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data));
> > > > return ((void *)IEEE80211_SKB_CB(skb)-
> > > > >status.status_driver_data);
> > > > }
> > >
> > > Hi Roy,
> > >
> > > I still do not understand since mt76_tx_status_skb_add() sets to
> > > 0 just sizeof
> > > of mt76_tx_cb, that according to pahole is 16 bytes, so it can't
> > > overwrite
> > > hw_key pointer (whose offset respect to the beginning of the
> > > control struct is
> > > 24, 32 - 8).
> > >
> > > Regards,
> > > Lorenzo
> > >
> > > >
> > > > Regards,
> > > > Roy Luo
> >
> > Hi Lorenzo,
> >
> > The mt76_tx_status_skb_add() memset zero the 16 bytes starting from
> > status.status_driver_data (please see the above inline function
> > shared
> > in my last response) whose offset with respect to the beginning of
> > the control/status union is exactly 24 (32 - 8) instead of 0.
> >
> > Regards,
> > Roy Luo
>
> Hi Roy,
>
> I can see the issue now, I was confusing status.status_driver_data
> with
> driver_data. You are right, we have an issue here. However, copying
> all the
> ieee80211_tx_info struct seems a bit overkill, what do you think?
> Moreover, we have the same issue for various chipsets (e.g. mt7925
> and
> mt7915). I guess we should try to find a global solution for the
> problem.
>
> Regards,
> Lorenzo
What about adding an helper for cb operation?
+void
+mt76_tx_status_skb_cb_add(struct mt76_dev *dev, struct sk_buff *skb,
+ struct mt76_wcid *wcid, int pid)
+{
+ struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb);
+
+ memset(cb, 0, sizeof(*cb));
+
+ spin_lock_bh(&dev->status_lock);
+ cb->wcid = wcid->idx;
+ cb->pktid = pid;
+ spin_unlock_bh(&dev->status_lock);
+}
+EXPORT_SYMBOL_GPL(mt76_tx_status_skb_cb_add);
And add this for each chipset.
index 061ab66..d0b67a2 100644
--- a/mt7996/mac.c
+++ b/mt7996/mac.c
@@ -1108,6 +1108,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev,
void *txwi_ptr,
if (!is_8023 || pid >= MT_PACKET_ID_FIRST)
mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb,
wcid, key,
pid, qid, 0);
+ mt76_tx_status_skb_cb_add(dev, tx_info->skb, wcid, pid);
^ permalink raw reply related
* Re: [PATCH 4/8] drm/panthor: Add support for protected memory allocation in panthor
From: Boris Brezillon @ 2026-05-19 17:29 UTC (permalink / raw)
To: Chia-I Wu
Cc: Ketil Johnsen, Liviu Dudau, Marcin Ślusarz, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Jonathan Corbet, Shuah Khan, Sumit Semwal,
Benjamin Gaignard, Brian Starkey, John Stultz, T.J. Mercier,
Christian König, Steven Price, Daniel Almeida, Alice Ryhl,
Matthias Brugger, AngeloGioacchino Del Regno, dri-devel,
linux-doc, linux-kernel, linux-media, linaro-mm-sig,
linux-arm-kernel, linux-mediatek, Florent Tomasin, nd
In-Reply-To: <CAPaKu7T7JZRmsS+D_3zFZtyhJk9mNXjL=xpAQ-UNGbm0vztyRg@mail.gmail.com>
On Tue, 19 May 2026 10:07:02 -0700
Chia-I Wu <olvaffe@gmail.com> wrote:
> On Tue, May 19, 2026 at 1:49 AM Ketil Johnsen <ketil.johnsen@arm.com> wrote:
> >
> > On 19/05/2026 09:39, Boris Brezillon wrote:
> > > On Mon, 18 May 2026 17:36:40 -0700
> > > Chia-I Wu <olvaffe@gmail.com> wrote:
> > >
> > >> On Mon, May 18, 2026 at 12:16 AM Boris Brezillon
> > >> <boris.brezillon@collabora.com> wrote:
> > >>>
> > >>> On Wed, 13 May 2026 12:31:32 -0700
> > >>> Chia-I Wu <olvaffe@gmail.com> wrote:
> > >>>
> > >>>> On Tue, May 12, 2026 at 8:39 AM Liviu Dudau <liviu.dudau@arm.com> wrote:
> > >>>>>
> > >>>>> On Tue, May 12, 2026 at 04:11:11PM +0200, Boris Brezillon wrote:
> > >>>>>> On Tue, 12 May 2026 14:47:27 +0100
> > >>>>>> Liviu Dudau <liviu.dudau@arm.com> wrote:
> > >>>>>>
> > >>>>>>> On Thu, May 07, 2026 at 01:53:56PM +0200, Boris Brezillon wrote:
> > >>>>>>>> On Thu, 7 May 2026 11:02:26 +0200
> > >>>>>>>> Marcin Ślusarz <marcin.slusarz@arm.com> wrote:
> > >>>>>>>>
> > >>>>>>>>> On Tue, May 05, 2026 at 06:15:23PM +0200, Boris Brezillon wrote:
> > >>>>>>>>>>> @@ -277,9 +286,21 @@ int panthor_device_init(struct panthor_device *ptdev)
> > >>>>>>>>>>> return ret;
> > >>>>>>>>>>> }
> > >>>>>>>>>>>
> > >>>>>>>>>>> + /* If a protected heap name is specified but not found, defer the probe until created */
> > >>>>>>>>>>> + if (protected_heap_name && strlen(protected_heap_name)) {
> > >>>>>>>>>>
> > >>>>>>>>>> Do we really need this strlen() > 0? Won't dma_heap_find() fail is the
> > >>>>>>>>>> name is "" already?
> > >>>>>>>>>
> > >>>>>>>>> If dma_heap_find() will fail, then the whole probe with fail too.
> > >>>>>>>>> This check prevents that.
> > >>>>>>>>
> > >>>>>>>> Yeah, that's also a questionable design choice. I mean, we can
> > >>>>>>>> currently probe and boot the FW even though we never setup the
> > >>>>>>>> protected FW sections, so why should we defer the probe here? Can't we
> > >>>>>>>> just retry the next time a group with the protected bit is created and
> > >>>>>>>> fail if we can find a protected heap?
> > >>>>>>>
> > >>>>>>> The problem we have with the current firmware is that it does a number of setup steps at "boot"
> > >>>>>>> time only. One of the steps is preparing its internal structures for when it enters protected
> > >>>>>>> mode and it stores them in the buffer passed in at firmware loading. We cannot later run the
> > >>>>>>> process when we have a group with protected mode set.
> > >>>>>>
> > >>>>>> No, but we can force a full/slow reset and have that thing
> > >>>>>> re-initialized, can't we? I mean, that's basically what we do when a
> > >>>>>> fast reset fails: we re-initialize all the sections and reset again, at
> > >>>>>> which point the FW should start from a fresh state, and be able to
> > >>>>>> properly initialize the protected-related stuff if protected sections
> > >>>>>> are populated. Am I missing something?
> > >>>>>
> > >>>>> Right, we can do that. For some reason I keep associating the reset with the
> > >>>>> error handling and not with "normal" operations.
> > >>>> I kind of hope we end up with either
> > >>>>
> > >>>> - panthor knows the exact heap to use and fails with EPROBE_DEFER if
> > >>>> the heap is missing, or
> > >>>> - panthor gets a dma-buf from userspace and does the full reset
> > >>>> - userspace also needs to provide a dma-buf for each protected
> > >>>> group for the suspend buffer
> > >>>>
> > >>>> than something in-between. The latter is more ad-hoc and basically
> > >>>> kicks the issue to the userspace.
> > >>>
> > >>> Indeed, the second option is more ad-hoc, but when you think about it,
> > >>> userspace has to have this knowledge, because it needs to know the
> > >>> dma-heap to use for buffer allocation that cross a device boundary
> > >>> anyway. Think about frames produced by a video decoder, and composited
> > >>> by the GPU into a protected scanout buffer that's passed to the KMS
> > >>> device. Why would the GPU driver be source of truth when it comes to
> > >>> choosing the heap to use to allocate protected buffers for the video
> > >>> decoder or those used for the display?
> > >> I don't think the GPU driver is ever the source of truth. If the
> > >> system integrator wants to specify the source of truth (SoT) from
> > >> kernel space, they should use the device tree (or module params /
> > >> config options). If they want to specify the SoT in userspace, then we
> > >> don't really care how it is done other than providing an ioctl.
> > >> Panthor is always on the receiving end.
> > >
> > > Okay, we're on the same page then.
> > >
> > >>
> > >> If we don't want to delay this functionality, but it takes time to
> > >> converge on SoT, maybe a solution that is not a long-term promise can
> > >> work? Of the options on the table (dt, module params, kconfig options,
> > >> ioctls), a kconfig option, potentially marked as experimental, seems
> > >> like a good candidate.
> > >
> > > If Panthor is only a consumer, I actually think it'd be easier to just
> > > let userspace pass the protected FW section as an imported buffer
> > > through an ioctl for now. It means we don't need any of the
> > > modifications to the dma_heap API in this series, and userspace is free
> > > to choose its SoT (efuse, DT, ...) and pass the info back to mesa/GBM
> > > somehow (envvar, driconf, ...). The only thing we need to ensure is if
> > > lazy protected FW section allocation is going to work, but given the
> > > current code purely and simply ignores those sections, and the FW is
> > > still able to boot and act properly (at least on v10-v13), I'm pretty
> > > confident this is okay, unless there's some trick the MCU can do to
> > > detect that the protected section isn't mapped (which I doubt, because
> > > the MCU doesn't know it lives behind an MMU).
> I set up MMU to map non-protected memory to the protected section the
> other day. The FW still booted fine. I didn't get access violation
> until the FW executed PROT_REGION and panthor requested
> GLB_PROTM_ENTER in response.
Ah, thanks for testing! We still don't have a setup with proper
protected heap, but that was on my list of things to test.
>
> This was on v13, but I also doubt it will become an issue. Can ARM help clarify?
>
> > >
> > > Of course, once we have a consensus on how to describe this in the DT,
> > > we can switch Panthor over to "protected dma_heap selection through DT",
> > > and reflect that through the ioctl that exposes whether protected
> > > support is ready or not (would be a DEV_QUERY), such that userspace can
> > > skip this "PROTM initialization" step.
> > >
> > > We're talking about an extra ioctl to set those buffers, and a
> > > DEV_QUERY to query the state (ready or not), the size of the global
> > > protected buffer (protected FW section) and the size of the protected
> > > suspend buffer. The protected suspend buffer would be allocated and
> > > passed at group creation time (extra arg passed to the existing
> > > GROUP_CREATE ioctl). So, overall, I don't consider it a huge liability
> > > in term of maintenance cost.
> >
> > If we can avoid the dma-heap changes, then that would surely help!
> > I can try to implement this in the next version unless someone finds a
> > reason why it is a bad idea.
> Yeah, that sounds good to me too.
>
> Will the extra ioctl require root?
The PROTM_INIT ioctl will certainly require high privilege
CAP_SYS_<something>, dunno yet what that <something> would be though.
> On a system with true protected
> memory, the FW cannot write to non-protected memory. It seems ok to
> allow any client to make the ioctl call. But on systems without true
> protected memory, it can be problematic.
Yep, I agree we shouldn't let random users pretend they initialized
protected mode if the system as a whole doesn't have proper the proper
bit hooked up to set that up.
^ permalink raw reply
* Re: [PATCH 4/8] drm/panthor: Add support for protected memory allocation in panthor
From: Chia-I Wu @ 2026-05-19 17:07 UTC (permalink / raw)
To: Ketil Johnsen
Cc: Boris Brezillon, Liviu Dudau, Marcin Ślusarz, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Jonathan Corbet, Shuah Khan, Sumit Semwal,
Benjamin Gaignard, Brian Starkey, John Stultz, T.J. Mercier,
Christian König, Steven Price, Daniel Almeida, Alice Ryhl,
Matthias Brugger, AngeloGioacchino Del Regno, dri-devel,
linux-doc, linux-kernel, linux-media, linaro-mm-sig,
linux-arm-kernel, linux-mediatek, Florent Tomasin, nd
In-Reply-To: <8f0b1750-a853-4895-9672-73a75f6dbd84@arm.com>
On Tue, May 19, 2026 at 1:49 AM Ketil Johnsen <ketil.johnsen@arm.com> wrote:
>
> On 19/05/2026 09:39, Boris Brezillon wrote:
> > On Mon, 18 May 2026 17:36:40 -0700
> > Chia-I Wu <olvaffe@gmail.com> wrote:
> >
> >> On Mon, May 18, 2026 at 12:16 AM Boris Brezillon
> >> <boris.brezillon@collabora.com> wrote:
> >>>
> >>> On Wed, 13 May 2026 12:31:32 -0700
> >>> Chia-I Wu <olvaffe@gmail.com> wrote:
> >>>
> >>>> On Tue, May 12, 2026 at 8:39 AM Liviu Dudau <liviu.dudau@arm.com> wrote:
> >>>>>
> >>>>> On Tue, May 12, 2026 at 04:11:11PM +0200, Boris Brezillon wrote:
> >>>>>> On Tue, 12 May 2026 14:47:27 +0100
> >>>>>> Liviu Dudau <liviu.dudau@arm.com> wrote:
> >>>>>>
> >>>>>>> On Thu, May 07, 2026 at 01:53:56PM +0200, Boris Brezillon wrote:
> >>>>>>>> On Thu, 7 May 2026 11:02:26 +0200
> >>>>>>>> Marcin Ślusarz <marcin.slusarz@arm.com> wrote:
> >>>>>>>>
> >>>>>>>>> On Tue, May 05, 2026 at 06:15:23PM +0200, Boris Brezillon wrote:
> >>>>>>>>>>> @@ -277,9 +286,21 @@ int panthor_device_init(struct panthor_device *ptdev)
> >>>>>>>>>>> return ret;
> >>>>>>>>>>> }
> >>>>>>>>>>>
> >>>>>>>>>>> + /* If a protected heap name is specified but not found, defer the probe until created */
> >>>>>>>>>>> + if (protected_heap_name && strlen(protected_heap_name)) {
> >>>>>>>>>>
> >>>>>>>>>> Do we really need this strlen() > 0? Won't dma_heap_find() fail is the
> >>>>>>>>>> name is "" already?
> >>>>>>>>>
> >>>>>>>>> If dma_heap_find() will fail, then the whole probe with fail too.
> >>>>>>>>> This check prevents that.
> >>>>>>>>
> >>>>>>>> Yeah, that's also a questionable design choice. I mean, we can
> >>>>>>>> currently probe and boot the FW even though we never setup the
> >>>>>>>> protected FW sections, so why should we defer the probe here? Can't we
> >>>>>>>> just retry the next time a group with the protected bit is created and
> >>>>>>>> fail if we can find a protected heap?
> >>>>>>>
> >>>>>>> The problem we have with the current firmware is that it does a number of setup steps at "boot"
> >>>>>>> time only. One of the steps is preparing its internal structures for when it enters protected
> >>>>>>> mode and it stores them in the buffer passed in at firmware loading. We cannot later run the
> >>>>>>> process when we have a group with protected mode set.
> >>>>>>
> >>>>>> No, but we can force a full/slow reset and have that thing
> >>>>>> re-initialized, can't we? I mean, that's basically what we do when a
> >>>>>> fast reset fails: we re-initialize all the sections and reset again, at
> >>>>>> which point the FW should start from a fresh state, and be able to
> >>>>>> properly initialize the protected-related stuff if protected sections
> >>>>>> are populated. Am I missing something?
> >>>>>
> >>>>> Right, we can do that. For some reason I keep associating the reset with the
> >>>>> error handling and not with "normal" operations.
> >>>> I kind of hope we end up with either
> >>>>
> >>>> - panthor knows the exact heap to use and fails with EPROBE_DEFER if
> >>>> the heap is missing, or
> >>>> - panthor gets a dma-buf from userspace and does the full reset
> >>>> - userspace also needs to provide a dma-buf for each protected
> >>>> group for the suspend buffer
> >>>>
> >>>> than something in-between. The latter is more ad-hoc and basically
> >>>> kicks the issue to the userspace.
> >>>
> >>> Indeed, the second option is more ad-hoc, but when you think about it,
> >>> userspace has to have this knowledge, because it needs to know the
> >>> dma-heap to use for buffer allocation that cross a device boundary
> >>> anyway. Think about frames produced by a video decoder, and composited
> >>> by the GPU into a protected scanout buffer that's passed to the KMS
> >>> device. Why would the GPU driver be source of truth when it comes to
> >>> choosing the heap to use to allocate protected buffers for the video
> >>> decoder or those used for the display?
> >> I don't think the GPU driver is ever the source of truth. If the
> >> system integrator wants to specify the source of truth (SoT) from
> >> kernel space, they should use the device tree (or module params /
> >> config options). If they want to specify the SoT in userspace, then we
> >> don't really care how it is done other than providing an ioctl.
> >> Panthor is always on the receiving end.
> >
> > Okay, we're on the same page then.
> >
> >>
> >> If we don't want to delay this functionality, but it takes time to
> >> converge on SoT, maybe a solution that is not a long-term promise can
> >> work? Of the options on the table (dt, module params, kconfig options,
> >> ioctls), a kconfig option, potentially marked as experimental, seems
> >> like a good candidate.
> >
> > If Panthor is only a consumer, I actually think it'd be easier to just
> > let userspace pass the protected FW section as an imported buffer
> > through an ioctl for now. It means we don't need any of the
> > modifications to the dma_heap API in this series, and userspace is free
> > to choose its SoT (efuse, DT, ...) and pass the info back to mesa/GBM
> > somehow (envvar, driconf, ...). The only thing we need to ensure is if
> > lazy protected FW section allocation is going to work, but given the
> > current code purely and simply ignores those sections, and the FW is
> > still able to boot and act properly (at least on v10-v13), I'm pretty
> > confident this is okay, unless there's some trick the MCU can do to
> > detect that the protected section isn't mapped (which I doubt, because
> > the MCU doesn't know it lives behind an MMU).
I set up MMU to map non-protected memory to the protected section the
other day. The FW still booted fine. I didn't get access violation
until the FW executed PROT_REGION and panthor requested
GLB_PROTM_ENTER in response.
This was on v13, but I also doubt it will become an issue. Can ARM help clarify?
> >
> > Of course, once we have a consensus on how to describe this in the DT,
> > we can switch Panthor over to "protected dma_heap selection through DT",
> > and reflect that through the ioctl that exposes whether protected
> > support is ready or not (would be a DEV_QUERY), such that userspace can
> > skip this "PROTM initialization" step.
> >
> > We're talking about an extra ioctl to set those buffers, and a
> > DEV_QUERY to query the state (ready or not), the size of the global
> > protected buffer (protected FW section) and the size of the protected
> > suspend buffer. The protected suspend buffer would be allocated and
> > passed at group creation time (extra arg passed to the existing
> > GROUP_CREATE ioctl). So, overall, I don't consider it a huge liability
> > in term of maintenance cost.
>
> If we can avoid the dma-heap changes, then that would surely help!
> I can try to implement this in the next version unless someone finds a
> reason why it is a bad idea.
Yeah, that sounds good to me too.
Will the extra ioctl require root? On a system with true protected
memory, the FW cannot write to non-protected memory. It seems ok to
allow any client to make the ioctl call. But on systems without true
protected memory, it can be problematic.
>
> >>>> For the former, expressing the relation in DT seems to be the best,
> >>>> but only if possible :-). Otherwise, a kconfig option (instead of
> >>>> module param) should be easier to work with.
> >>>>
> >>>> Looking at the userspace implementation, can we also have an panthor
> >>>> ioctl to return the heap to userspace?
> >>>
> >>> Yes, it's something we can add, but again, I'm questioning the
> >>> usefulness of this: how can we ensure the heap used by panthor to
> >>> allocate its protected FW buffers is suitable for scanout buffers
> >>> (buffers that can be used by display drivers). There needs to be a glue
> >>> leaving in usersland and taking the decision, and I'm not too sure
> >>> trusting any of the component in the chain (vdec, gpu, display) is the
> >>> right thing to do.
> >> The heap returned by panthor is only for panfrost/panvk. It says
> >> nothing about compatibility with other components on the system.
> >
> > Okay, if it's used only for internal buffers, I guess that's fine.
>
> --
> Ketil
^ permalink raw reply
* Re: [PATCH] PCI: mediatek-gen3: fix incorrectly skipped pwrctrl error message
From: Manivannan Sadhasivam @ 2026-05-19 14:27 UTC (permalink / raw)
To: Matthias Brugger, AngeloGioacchino Del Regno, Ryder Lee,
Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
Bjorn Helgaas, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai
Cc: devicetree, linux-pci, linux-mediatek, linux-kernel,
Dan Carpenter
In-Reply-To: <20260512103347.1751080-1-wenst@chromium.org>
On Tue, 12 May 2026 18:33:45 +0800, Chen-Yu Tsai wrote:
> When pwrctrl integration was added, the error message for when
> pci_pwrctrl_create_devices() fails was incorrectly put after the error
> goto statement, causing it to be skipped.
>
> Move the goto statement after the dev_err_probe() call so that the
> error message actually gets printed (or saved if probe is deferred).
>
> [...]
Applied, thanks!
[1/1] PCI: mediatek-gen3: fix incorrectly skipped pwrctrl error message
commit: 8ba433753d9b131c2e43b1ff7ba8c5730cef8231
Best regards,
--
Manivannan Sadhasivam <mani@kernel.org>
^ permalink raw reply
* Re: [PATCH] wifi: mt76: mt7996: avoid memset overwriting tx_info->control.flags
From: Lorenzo Bianconi @ 2026-05-19 12:24 UTC (permalink / raw)
To: Roy Luo
Cc: Lorenzo Bianconi, Ryder Lee, Felix Fietkau, linux-mediatek,
linux-wireless, Shayne Chen, Roy Luo
In-Reply-To: <CAHoxojKeXCCnJoO7yBBmTM9euiTf38orujOhOK00X8bb3ctWuA@mail.gmail.com>
>
> On Mon, May 18, 2026 at 5:31 AM Lorenzo Bianconi <lorenzo@kernel.org> wrote:
> >
> > On May 15, Cheng Hao Luo wrote:
> > > > struct ieee80211_tx_info {
> > > > u32 flags; /* 0 4 */
> > > > u32 band:3; /* 4: 0 4 */
> > > > u32 status_data_idr:1; /* 4: 3 4 */
> > > > u32 status_data:13; /* 4: 4 4 */
> > > > u32 hw_queue:4; /* 4:17 4 */
> > > > u32 tx_time_est:10; /* 4:21 4 */
> > > >
> > > > /* XXX 1 bit hole, try to pack */
> > > >
> > > > union {
> > > > struct {
> > > > union {
> > > > struct {
> > > > struct ieee80211_tx_rate rates[4]; /* 8 12 */
> > > > s8 rts_cts_rate_idx; /* 20 1 */
> > > > u8 use_rts:1; /* 21: 0 1 */
> > > > u8 use_cts_prot:1; /* 21: 1 1 */
> > > > u8 short_preamble:1; /* 21: 2 1 */
> > > > u8 skip_table:1; /* 21: 3 1 */
> > > > u8 antennas:2; /* 21: 4 1 */
> > > > }; /* 8 14 */
> > > > long unsigned int jiffies; /* 8 8 */
> > > > }; /* 8 16 */
> > > > struct ieee80211_vif * vif; /* 24 8 */
> > > > struct ieee80211_key_conf * hw_key; /* 32 8 */
> > > > u32 flags; /* 40 4 */
> > > > codel_time_t enqueue_time; /* 44 4 */
> > > > } control; /* 8 40 */
> > > > struct {
> > > > u64 cookie; /* 8 8 */
> > > > } ack; /* 8 8 */
> > > > struct {
> > > > struct ieee80211_tx_rate rates[4]; /* 8 12 */
> > > > s32 ack_signal; /* 20 4 */
> > > > u8 ampdu_ack_len; /* 24 1 */
> > > > u8 ampdu_len; /* 25 1 */
> > > > u8 antenna; /* 26 1 */
> > > > u8 pad; /* 27 1 */
> > > > u16 tx_time; /* 28 2 */
> > > > u8 flags; /* 30 1 */
> > > > u8 pad2; /* 31 1 */
> > > > void * status_driver_data[2]; /* 32 16 */
> > > > } status; /* 8 40 */
> > > > struct {
> > > > struct ieee80211_tx_rate driver_rates[4]; /* 8 12 */
> > > > u8 pad[4]; /* 20 4 */
> > > > void * rate_driver_data[3]; /* 24 24 */
> > > > }; /* 8 40 */
> > > > void * driver_data[5]; /* 8 40 */
> > > > }; /* 8 40 */
> > > >
> > > > /* size: 48, cachelines: 1, members: 7 */
> > > > /* sum members: 44 */
> > > > /* sum bitfield members: 31 bits, bit holes: 1, sum bit holes: 1 bits */
> > > > /* last cacheline: 48 bytes */
> > > > };
> > > >
> > > > According to pahole, the size of the control inner union is actually 16 bytes
> > > > since the compiler adds 2 bytes of padding. Since mt76_tx_status_skb_add()
> > > > meset to 0 just mt76_tx_cb size (that is 16 bytes) I can't see how
> > > > control.flags is overwritten. Am I missing something?
> > > >
> > > > struct mt76_tx_cb {
> > > > long unsigned int jiffies; /* 0 8 */
> > > > u16 wcid; /* 8 2 */
> > > > u8 pktid; /* 10 1 */
> > > > u8 flags; /* 11 1 */
> > > >
> > > > /* size: 16, cachelines: 1, members: 4 */
> > > > /* padding: 4 */
> > > > /* last cacheline: 16 bytes */
> > > > };
> > >
> > > Hi Lorenzo,
> > >
> > > The mt76_tx_cb is placed at status.status_driver_data (offset 32).
> > > It overlaps with hw_key, flags and enqueue_time in the control union.
> > >
> > > static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb)
> > > {
> > > BUILD_BUG_ON(sizeof(struct mt76_tx_cb) >
> > > sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data));
> > > return ((void *)IEEE80211_SKB_CB(skb)->status.status_driver_data);
> > > }
> >
> > Hi Roy,
> >
> > I still do not understand since mt76_tx_status_skb_add() sets to 0 just sizeof
> > of mt76_tx_cb, that according to pahole is 16 bytes, so it can't overwrite
> > hw_key pointer (whose offset respect to the beginning of the control struct is
> > 24, 32 - 8).
> >
> > Regards,
> > Lorenzo
> >
> > >
> > > Regards,
> > > Roy Luo
>
> Hi Lorenzo,
>
> The mt76_tx_status_skb_add() memset zero the 16 bytes starting from
> status.status_driver_data (please see the above inline function shared
> in my last response) whose offset with respect to the beginning of
> the control/status union is exactly 24 (32 - 8) instead of 0.
>
> Regards,
> Roy Luo
Hi Roy,
I can see the issue now, I was confusing status.status_driver_data
with
driver_data. You are right, we have an issue here. However, copying
all the
ieee80211_tx_info struct seems a bit overkill, what do you think?
Moreover, we have the same issue for various chipsets (e.g. mt7925 and
mt7915). I guess we should try to find a global solution for the
problem.
Regards,
Lorenzo
^ permalink raw reply
* Re: [Linaro-mm-sig] Re: [PATCH 4/8] drm/panthor: Add support for protected memory allocation in panthor
From: Boris Brezillon @ 2026-05-19 11:37 UTC (permalink / raw)
To: Maxime Ripard
Cc: Chia-I Wu, Liviu Dudau, Marcin Ślusarz, Ketil Johnsen,
David Airlie, Simona Vetter, Maarten Lankhorst, Thomas Zimmermann,
Jonathan Corbet, Shuah Khan, Sumit Semwal, Benjamin Gaignard,
Brian Starkey, John Stultz, T.J. Mercier, Christian König,
Steven Price, Daniel Almeida, Alice Ryhl, Matthias Brugger,
AngeloGioacchino Del Regno, dri-devel, linux-doc, linux-kernel,
linux-media, linaro-mm-sig, linux-arm-kernel, linux-mediatek,
Florent Tomasin, nd
In-Reply-To: <20260519-loutish-beautiful-trogon-67453f@houat>
On Tue, 19 May 2026 11:52:13 +0200
Maxime Ripard <mripard@kernel.org> wrote:
> Hi Boris,
>
> On Mon, May 18, 2026 at 09:16:50AM +0200, Boris Brezillon wrote:
> > On Wed, 13 May 2026 12:31:32 -0700
> > Chia-I Wu <olvaffe@gmail.com> wrote:
> >
> > > On Tue, May 12, 2026 at 8:39 AM Liviu Dudau <liviu.dudau@arm.com> wrote:
> > > >
> > > > On Tue, May 12, 2026 at 04:11:11PM +0200, Boris Brezillon wrote:
> > > > > On Tue, 12 May 2026 14:47:27 +0100
> > > > > Liviu Dudau <liviu.dudau@arm.com> wrote:
> > > > >
> > > > > > On Thu, May 07, 2026 at 01:53:56PM +0200, Boris Brezillon wrote:
> > > > > > > On Thu, 7 May 2026 11:02:26 +0200
> > > > > > > Marcin Ślusarz <marcin.slusarz@arm.com> wrote:
> > > > > > >
> > > > > > > > On Tue, May 05, 2026 at 06:15:23PM +0200, Boris Brezillon wrote:
> > > > > > > > > > @@ -277,9 +286,21 @@ int panthor_device_init(struct panthor_device *ptdev)
> > > > > > > > > > return ret;
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > + /* If a protected heap name is specified but not found, defer the probe until created */
> > > > > > > > > > + if (protected_heap_name && strlen(protected_heap_name)) {
> > > > > > > > >
> > > > > > > > > Do we really need this strlen() > 0? Won't dma_heap_find() fail is the
> > > > > > > > > name is "" already?
> > > > > > > >
> > > > > > > > If dma_heap_find() will fail, then the whole probe with fail too.
> > > > > > > > This check prevents that.
> > > > > > >
> > > > > > > Yeah, that's also a questionable design choice. I mean, we can
> > > > > > > currently probe and boot the FW even though we never setup the
> > > > > > > protected FW sections, so why should we defer the probe here? Can't we
> > > > > > > just retry the next time a group with the protected bit is created and
> > > > > > > fail if we can find a protected heap?
> > > > > >
> > > > > > The problem we have with the current firmware is that it does a number of setup steps at "boot"
> > > > > > time only. One of the steps is preparing its internal structures for when it enters protected
> > > > > > mode and it stores them in the buffer passed in at firmware loading. We cannot later run the
> > > > > > process when we have a group with protected mode set.
> > > > >
> > > > > No, but we can force a full/slow reset and have that thing
> > > > > re-initialized, can't we? I mean, that's basically what we do when a
> > > > > fast reset fails: we re-initialize all the sections and reset again, at
> > > > > which point the FW should start from a fresh state, and be able to
> > > > > properly initialize the protected-related stuff if protected sections
> > > > > are populated. Am I missing something?
> > > >
> > > > Right, we can do that. For some reason I keep associating the reset with the
> > > > error handling and not with "normal" operations.
> > > I kind of hope we end up with either
> > >
> > > - panthor knows the exact heap to use and fails with EPROBE_DEFER if
> > > the heap is missing, or
> > > - panthor gets a dma-buf from userspace and does the full reset
> > > - userspace also needs to provide a dma-buf for each protected
> > > group for the suspend buffer
> > >
> > > than something in-between. The latter is more ad-hoc and basically
> > > kicks the issue to the userspace.
> >
> > Indeed, the second option is more ad-hoc, but when you think about it,
> > userspace has to have this knowledge, because it needs to know the
> > dma-heap to use for buffer allocation that cross a device boundary
> > anyway. Think about frames produced by a video decoder, and composited
> > by the GPU into a protected scanout buffer that's passed to the KMS
> > device. Why would the GPU driver be source of truth when it comes to
> > choosing the heap to use to allocate protected buffers for the video
> > decoder or those used for the display?
>
> Just fyi, the trend is to go to devices listing the heaps userspace
> should allocate from
Devices listing the heaps they are able to import buffers from
(with the list being different based on the buffer properties, I
guess) is a good thing. This way the central allocator is in a position
where it can intersect the devices lists and decide which heap to
allocate from based on its buffer sharing knowledge.
> and/or using the heaps internally to allocate their
> buffers,
Yes, that too. For internal buffers (especially the device-wide ones,
like the protected FW sections we were discussing), it makes sense to
leave that up to the driver.
> so that last part is where we're headed, and feels totally
> reasonable to me.
Just to be clear, my main concern right now is not the long term plan,
but how realistic it is to assume we'll have all the DT/dma_heap pieces
in place in a reasonable amount of time. Looking at the current state
of affairs (based on this patchset), it feels like we're a long way
till we can have a robust way of exposing dma_heaps to in-kernel users
(refcounting, lifetime issues, describing allowed heaps, ensuring heaps
truly provide buffers with the expected properties, ...). I'm certainly
not saying these are not valid concerns, but I'd like to have a
temporary solution to support protected rendering in the meantime...
>
> Maxime
^ permalink raw reply
* Re: [PATCH net v2 0/5] net: dsa: mt7530: assorted fixes
From: patchwork-bot+netdevbpf @ 2026-05-19 11:00 UTC (permalink / raw)
To: Daniel Golle
Cc: chester.a.unal, andrew, olteanv, davem, edumazet, kuba, pabeni,
matthias.bgg, angelogioacchino.delregno, dqfext, f.fainelli,
arinc.unal, sean.wang, netdev, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <cover.1778766629.git.daniel@makrotopia.org>
Hello:
This series was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Thu, 14 May 2026 15:04:06 +0100 you wrote:
> A batch of small, independent fixes for the MediaTek MT7530 family DSA
> driver, addressing long-standing correctness issues that surface on
> hardware with bridge VLAN filtering enabled, on link-local frame
> reception, and during bridge join/leave transitions.
> ---
> Changes since v1:
> - rework patch 1/5 following up Paolo Abeni and Sashiko reviews
>
> [...]
Here is the summary with links:
- [net,v2,1/5] net: dsa: mt7530: fix FDB entries not aging out with short timeout
https://git.kernel.org/netdev/net/c/e824e40d0e84
- [net,v2,2/5] net: dsa: mt7530: preserve VLAN tags on trapped link-local frames
https://git.kernel.org/netdev/net/c/3ac85bcfd404
- [net,v2,3/5] net: dsa: mt7530: fix CPU port VLAN not being reset to unaware
https://git.kernel.org/netdev/net/c/2c4c76cacc9d
- [net,v2,4/5] net: dsa: mt7530: clear flood flags on bridge leave
(no matching commit)
- [net,v2,5/5] net: dsa: mt7530: untag VLAN-aware bridge PVID
https://git.kernel.org/netdev/net/c/4cb3cd670b2a
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net v2 4/5] net: dsa: mt7530: clear flood flags on bridge leave
From: Paolo Abeni @ 2026-05-19 10:53 UTC (permalink / raw)
To: Daniel Golle, Chester A. Unal, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Matthias Brugger,
AngeloGioacchino Del Regno, DENG Qingfang, Florian Fainelli,
Arınç ÜNAL, Sean Wang, netdev, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <cc8d2f494dd202304a6f68332f3a90ea0a8a4618.1778766629.git.daniel@makrotopia.org>
On 5/14/26 4:05 PM, Daniel Golle wrote:
> Flood flags set by port_bridge_flags persist after a port leaves the
> bridge, causing unknown unicast to be forwarded to standalone ports.
>
> Clear UNU_FFP, UNM_FFP and BC_FFP in port_bridge_leave so that the
> port returns to its initial state without flooding.
>
> Fixes: 5a30833b9a16 ("net: dsa: mt7530: support MDB and bridge flag operations")
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
> v2: no changes
>
> drivers/net/dsa/mt7530.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index 752ba92b0851..5b58e42bfda9 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -1767,6 +1767,11 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
> mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
> MT7530_PORT_MATRIX_MODE);
>
> + /* Clear flood flags so they don't persist across bridge leave */
> + mt7530_clear(priv, MT753X_MFC,
> + UNU_FFP(BIT(port)) | UNM_FFP(BIT(port)) |
> + BC_FFP(BIT(port)));
I think sashiko has a point here:
---
Will these cleared flags be immediately overwritten by the DSA core?
When a port leaves a bridge, the DSA core's dsa_port_bridge_leave()
broadcasts the DSA_NOTIFIER_BRIDGE_LEAVE event, which triggers this
callback and clears the bits.
However, immediately after the broadcast returns,
dsa_port_bridge_leave() unconditionally calls
dsa_port_switchdev_unsync_attrs(), which calls
dsa_port_clear_brport_flags().
This explicitly configures standalone ports to flood everything by
setting the BR_FLOOD, BR_MCAST_FLOOD, and BR_BCAST_FLOOD flags to 1, and
then invokes the driver's port_bridge_flags callback.
As a result, mt7530_port_bridge_flags() processes this call and executes
mt7530_rmw() to turn the UNU_FFP, UNM_FFP, and BC_FFP bits right back to
1 for the port.
Does this leave the isolation bug unfixed since the register clearing is
reverted before the DSA bridge leave sequence fully completes?
---
Since the other fixes are independent, I'm applying them.
/P
^ permalink raw reply
* Re: [PATCH v2 2/2] regulator: Use named initializers for arrays of i2c_device_data
From: Laurent Pinchart @ 2026-05-19 10:07 UTC (permalink / raw)
To: Uwe Kleine-König (The Capable Hub)
Cc: Liam Girdwood, Mark Brown, Michael Hennerich, Support Opensource,
Ivaylo Ivanov, Claudiu Beznea, Andrei Simion, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Woodrow Douglass,
Jagan Teki, Icenowy Zheng, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <9a8bfc7286221873ef02eeba0727eeaeb9e504e8.1779184320.git.u.kleine-koenig@baylibre.com>
On Tue, May 19, 2026 at 11:57:51AM +0200, Uwe Kleine-König (The Capable Hub) wrote:
> While being less compact, using named initializers allows to more easily
> see which members of the structs are assigned which value without having
> to lookup the declaration of the struct. And it's also more robust
> against changes to the struct definition.
>
> The mentioned robustness is relevant for a planned change to struct
> i2c_device_id that replaces .driver_data by an anonymous union.
>
> While touching all these arrays, unify usage of whitespace and commas.
>
> This patch doesn't modify the compiled arrays, only their representation
> in source form benefits. The former was confirmed with x86 and arm64
> builds.
>
> Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
> ---
> drivers/regulator/88pg86x.c | 4 +--
> drivers/regulator/ad5398.c | 4 +--
> drivers/regulator/da9121-regulator.c | 20 +++++++--------
> drivers/regulator/da9210-regulator.c | 4 +--
> drivers/regulator/da9211-regulator.c | 18 +++++++-------
> drivers/regulator/fan53880.c | 4 +--
> drivers/regulator/isl9305.c | 4 +--
> drivers/regulator/lp3971.c | 2 +-
> drivers/regulator/lp3972.c | 2 +-
> drivers/regulator/lp872x.c | 34 +++++++++++++-------------
> drivers/regulator/lp8755.c | 4 +--
> drivers/regulator/ltc3589.c | 6 ++---
> drivers/regulator/ltc3676.c | 2 +-
> drivers/regulator/max1586.c | 2 +-
> drivers/regulator/max20086-regulator.c | 8 +++---
> drivers/regulator/max20411-regulator.c | 2 +-
> drivers/regulator/max77503-regulator.c | 2 +-
> drivers/regulator/max77675-regulator.c | 2 +-
> drivers/regulator/max77826-regulator.c | 2 +-
> drivers/regulator/max77838-regulator.c | 2 +-
> drivers/regulator/max77857-regulator.c | 8 +++---
> drivers/regulator/max8649.c | 2 +-
> drivers/regulator/max8893.c | 2 +-
> drivers/regulator/max8952.c | 2 +-
> drivers/regulator/mcp16502.c | 2 +-
> drivers/regulator/mp5416.c | 6 ++---
> drivers/regulator/mp8859.c | 4 +--
> drivers/regulator/mp886x.c | 6 ++---
> drivers/regulator/mpq7920.c | 4 +--
> drivers/regulator/mt6311-regulator.c | 4 +--
> drivers/regulator/pf530x-regulator.c | 6 ++---
> drivers/regulator/pf8x00-regulator.c | 8 +++---
> drivers/regulator/pv88060-regulator.c | 4 +--
> drivers/regulator/pv88080-regulator.c | 8 +++---
> drivers/regulator/pv88090-regulator.c | 4 +--
> drivers/regulator/slg51000-regulator.c | 4 +--
> drivers/regulator/sy8106a-regulator.c | 2 +-
> drivers/regulator/sy8824x.c | 8 +++---
> drivers/regulator/sy8827n.c | 4 +--
> drivers/regulator/tps6286x-regulator.c | 10 ++++----
> drivers/regulator/tps6287x-regulator.c | 10 ++++----
> 41 files changed, 118 insertions(+), 118 deletions(-)
[snip]
> diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c
> index 942f37082cb1..779df653338a 100644
> --- a/drivers/regulator/lp872x.c
> +++ b/drivers/regulator/lp872x.c
> @@ -796,24 +796,24 @@ static const struct regmap_config lp872x_regmap_config = {
> #define LP872X_VALID_OPMODE (REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL)
>
> static struct of_regulator_match lp8720_matches[] = {
This is unrelated to the commit message that only mentions
i2c_device_id.
With this chunk dropped,
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> - { .name = "ldo1", .driver_data = (void *)LP8720_ID_LDO1, },
> - { .name = "ldo2", .driver_data = (void *)LP8720_ID_LDO2, },
> - { .name = "ldo3", .driver_data = (void *)LP8720_ID_LDO3, },
> - { .name = "ldo4", .driver_data = (void *)LP8720_ID_LDO4, },
> - { .name = "ldo5", .driver_data = (void *)LP8720_ID_LDO5, },
> - { .name = "buck", .driver_data = (void *)LP8720_ID_BUCK, },
> + { .name = "ldo1", .driver_data = (void *)LP8720_ID_LDO1 },
> + { .name = "ldo2", .driver_data = (void *)LP8720_ID_LDO2 },
> + { .name = "ldo3", .driver_data = (void *)LP8720_ID_LDO3 },
> + { .name = "ldo4", .driver_data = (void *)LP8720_ID_LDO4 },
> + { .name = "ldo5", .driver_data = (void *)LP8720_ID_LDO5 },
> + { .name = "buck", .driver_data = (void *)LP8720_ID_BUCK },
> };
>
> static struct of_regulator_match lp8725_matches[] = {
> - { .name = "ldo1", .driver_data = (void *)LP8725_ID_LDO1, },
> - { .name = "ldo2", .driver_data = (void *)LP8725_ID_LDO2, },
> - { .name = "ldo3", .driver_data = (void *)LP8725_ID_LDO3, },
> - { .name = "ldo4", .driver_data = (void *)LP8725_ID_LDO4, },
> - { .name = "ldo5", .driver_data = (void *)LP8725_ID_LDO5, },
> - { .name = "lilo1", .driver_data = (void *)LP8725_ID_LILO1, },
> - { .name = "lilo2", .driver_data = (void *)LP8725_ID_LILO2, },
> - { .name = "buck1", .driver_data = (void *)LP8725_ID_BUCK1, },
> - { .name = "buck2", .driver_data = (void *)LP8725_ID_BUCK2, },
> + { .name = "ldo1", .driver_data = (void *)LP8725_ID_LDO1 },
> + { .name = "ldo2", .driver_data = (void *)LP8725_ID_LDO2 },
> + { .name = "ldo3", .driver_data = (void *)LP8725_ID_LDO3 },
> + { .name = "ldo4", .driver_data = (void *)LP8725_ID_LDO4 },
> + { .name = "ldo5", .driver_data = (void *)LP8725_ID_LDO5 },
> + { .name = "lilo1", .driver_data = (void *)LP8725_ID_LILO1 },
> + { .name = "lilo2", .driver_data = (void *)LP8725_ID_LILO2 },
> + { .name = "buck1", .driver_data = (void *)LP8725_ID_BUCK1 },
> + { .name = "buck2", .driver_data = (void *)LP8725_ID_BUCK2 },
> };
>
> static struct lp872x_platform_data
> @@ -935,8 +935,8 @@ static const struct of_device_id lp872x_dt_ids[] __maybe_unused = {
> MODULE_DEVICE_TABLE(of, lp872x_dt_ids);
>
> static const struct i2c_device_id lp872x_ids[] = {
> - {"lp8720", LP8720},
> - {"lp8725", LP8725},
> + { .name = "lp8720", .driver_data = LP8720 },
> + { .name = "lp8725", .driver_data = LP8725 },
> { }
> };
> MODULE_DEVICE_TABLE(i2c, lp872x_ids);
[snip]
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH v2 2/2] regulator: Use named initializers for arrays of i2c_device_data
From: Uwe Kleine-König (The Capable Hub) @ 2026-05-19 9:57 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown
Cc: Michael Hennerich, Support Opensource, Laurent Pinchart,
Ivaylo Ivanov, Claudiu Beznea, Andrei Simion, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Woodrow Douglass,
Jagan Teki, Icenowy Zheng, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <cover.1779184320.git.u.kleine-koenig@baylibre.com>
While being less compact, using named initializers allows to more easily
see which members of the structs are assigned which value without having
to lookup the declaration of the struct. And it's also more robust
against changes to the struct definition.
The mentioned robustness is relevant for a planned change to struct
i2c_device_id that replaces .driver_data by an anonymous union.
While touching all these arrays, unify usage of whitespace and commas.
This patch doesn't modify the compiled arrays, only their representation
in source form benefits. The former was confirmed with x86 and arm64
builds.
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
---
drivers/regulator/88pg86x.c | 4 +--
drivers/regulator/ad5398.c | 4 +--
drivers/regulator/da9121-regulator.c | 20 +++++++--------
drivers/regulator/da9210-regulator.c | 4 +--
drivers/regulator/da9211-regulator.c | 18 +++++++-------
drivers/regulator/fan53880.c | 4 +--
drivers/regulator/isl9305.c | 4 +--
drivers/regulator/lp3971.c | 2 +-
drivers/regulator/lp3972.c | 2 +-
drivers/regulator/lp872x.c | 34 +++++++++++++-------------
drivers/regulator/lp8755.c | 4 +--
drivers/regulator/ltc3589.c | 6 ++---
drivers/regulator/ltc3676.c | 2 +-
drivers/regulator/max1586.c | 2 +-
drivers/regulator/max20086-regulator.c | 8 +++---
drivers/regulator/max20411-regulator.c | 2 +-
drivers/regulator/max77503-regulator.c | 2 +-
drivers/regulator/max77675-regulator.c | 2 +-
drivers/regulator/max77826-regulator.c | 2 +-
drivers/regulator/max77838-regulator.c | 2 +-
drivers/regulator/max77857-regulator.c | 8 +++---
drivers/regulator/max8649.c | 2 +-
drivers/regulator/max8893.c | 2 +-
drivers/regulator/max8952.c | 2 +-
drivers/regulator/mcp16502.c | 2 +-
drivers/regulator/mp5416.c | 6 ++---
drivers/regulator/mp8859.c | 4 +--
drivers/regulator/mp886x.c | 6 ++---
drivers/regulator/mpq7920.c | 4 +--
drivers/regulator/mt6311-regulator.c | 4 +--
drivers/regulator/pf530x-regulator.c | 6 ++---
drivers/regulator/pf8x00-regulator.c | 8 +++---
drivers/regulator/pv88060-regulator.c | 4 +--
drivers/regulator/pv88080-regulator.c | 8 +++---
drivers/regulator/pv88090-regulator.c | 4 +--
drivers/regulator/slg51000-regulator.c | 4 +--
drivers/regulator/sy8106a-regulator.c | 2 +-
drivers/regulator/sy8824x.c | 8 +++---
drivers/regulator/sy8827n.c | 4 +--
drivers/regulator/tps6286x-regulator.c | 10 ++++----
drivers/regulator/tps6287x-regulator.c | 10 ++++----
41 files changed, 118 insertions(+), 118 deletions(-)
diff --git a/drivers/regulator/88pg86x.c b/drivers/regulator/88pg86x.c
index e6598e74ec94..8c25a1db412f 100644
--- a/drivers/regulator/88pg86x.c
+++ b/drivers/regulator/88pg86x.c
@@ -92,8 +92,8 @@ static const struct of_device_id __maybe_unused pg86x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pg86x_dt_ids);
static const struct i2c_device_id pg86x_i2c_id[] = {
- { "88pg867", },
- { "88pg868", },
+ { .name = "88pg867" },
+ { .name = "88pg868" },
{ }
};
MODULE_DEVICE_TABLE(i2c, pg86x_i2c_id);
diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c
index eb2a666a45cb..0123ca8157a8 100644
--- a/drivers/regulator/ad5398.c
+++ b/drivers/regulator/ad5398.c
@@ -207,8 +207,8 @@ struct ad5398_current_data_format {
static const struct ad5398_current_data_format df_10_4_120 = {10, 4, 0, 120000};
static const struct i2c_device_id ad5398_id[] = {
- { "ad5398", (kernel_ulong_t)&df_10_4_120 },
- { "ad5821", (kernel_ulong_t)&df_10_4_120 },
+ { .name = "ad5398", .driver_data = (kernel_ulong_t)&df_10_4_120 },
+ { .name = "ad5821", .driver_data = (kernel_ulong_t)&df_10_4_120 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad5398_id);
diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c
index 2b150bb4d471..8155f0974f7d 100644
--- a/drivers/regulator/da9121-regulator.c
+++ b/drivers/regulator/da9121-regulator.c
@@ -1195,16 +1195,16 @@ static void da9121_i2c_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id da9121_i2c_id[] = {
- {"da9121", DA9121_TYPE_DA9121_DA9130},
- {"da9130", DA9121_TYPE_DA9121_DA9130},
- {"da9217", DA9121_TYPE_DA9217},
- {"da9122", DA9121_TYPE_DA9122_DA9131},
- {"da9131", DA9121_TYPE_DA9122_DA9131},
- {"da9220", DA9121_TYPE_DA9220_DA9132},
- {"da9132", DA9121_TYPE_DA9220_DA9132},
- {"da9141", DA9121_TYPE_DA9141},
- {"da9142", DA9121_TYPE_DA9142},
- {},
+ { .name = "da9121", .driver_data = DA9121_TYPE_DA9121_DA9130 },
+ { .name = "da9130", .driver_data = DA9121_TYPE_DA9121_DA9130 },
+ { .name = "da9217", .driver_data = DA9121_TYPE_DA9217 },
+ { .name = "da9122", .driver_data = DA9121_TYPE_DA9122_DA9131 },
+ { .name = "da9131", .driver_data = DA9121_TYPE_DA9122_DA9131 },
+ { .name = "da9220", .driver_data = DA9121_TYPE_DA9220_DA9132 },
+ { .name = "da9132", .driver_data = DA9121_TYPE_DA9220_DA9132 },
+ { .name = "da9141", .driver_data = DA9121_TYPE_DA9141 },
+ { .name = "da9142", .driver_data = DA9121_TYPE_DA9142 },
+ { }
};
MODULE_DEVICE_TABLE(i2c, da9121_i2c_id);
diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c
index 39ade0dba40f..9154e32bd745 100644
--- a/drivers/regulator/da9210-regulator.c
+++ b/drivers/regulator/da9210-regulator.c
@@ -202,8 +202,8 @@ static int da9210_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id da9210_i2c_id[] = {
- { "da9210" },
- {}
+ { .name = "da9210" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, da9210_i2c_id);
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c
index d4f14d7ea8cf..9cf713755636 100644
--- a/drivers/regulator/da9211-regulator.c
+++ b/drivers/regulator/da9211-regulator.c
@@ -522,15 +522,15 @@ static int da9211_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id da9211_i2c_id[] = {
- {"da9211", DA9211},
- {"da9212", DA9212},
- {"da9213", DA9213},
- {"da9223", DA9223},
- {"da9214", DA9214},
- {"da9224", DA9224},
- {"da9215", DA9215},
- {"da9225", DA9225},
- {},
+ { .name = "da9211", .driver_data = DA9211 },
+ { .name = "da9212", .driver_data = DA9212 },
+ { .name = "da9213", .driver_data = DA9213 },
+ { .name = "da9223", .driver_data = DA9223 },
+ { .name = "da9214", .driver_data = DA9214 },
+ { .name = "da9224", .driver_data = DA9224 },
+ { .name = "da9215", .driver_data = DA9215 },
+ { .name = "da9225", .driver_data = DA9225 },
+ { }
};
MODULE_DEVICE_TABLE(i2c, da9211_i2c_id);
diff --git a/drivers/regulator/fan53880.c b/drivers/regulator/fan53880.c
index 6cb5656845f9..79ba705ec324 100644
--- a/drivers/regulator/fan53880.c
+++ b/drivers/regulator/fan53880.c
@@ -164,8 +164,8 @@ static const struct of_device_id fan53880_dt_ids[] = {
MODULE_DEVICE_TABLE(of, fan53880_dt_ids);
static const struct i2c_device_id fan53880_i2c_id[] = {
- { "fan53880", },
- {}
+ { .name = "fan53880" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, fan53880_i2c_id);
diff --git a/drivers/regulator/isl9305.c b/drivers/regulator/isl9305.c
index 5a234f25e6bb..ec6bd6bb9721 100644
--- a/drivers/regulator/isl9305.c
+++ b/drivers/regulator/isl9305.c
@@ -186,8 +186,8 @@ MODULE_DEVICE_TABLE(of, isl9305_dt_ids);
#endif
static const struct i2c_device_id isl9305_i2c_id[] = {
- { "isl9305", },
- { "isl9305h", },
+ { .name = "isl9305" },
+ { .name = "isl9305h" },
{ }
};
MODULE_DEVICE_TABLE(i2c, isl9305_i2c_id);
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c
index d4dab86fe385..6f830ae1bb61 100644
--- a/drivers/regulator/lp3971.c
+++ b/drivers/regulator/lp3971.c
@@ -439,7 +439,7 @@ static int lp3971_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id lp3971_i2c_id[] = {
- { "lp3971" },
+ { .name = "lp3971" },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);
diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c
index 1b918fb72134..235c640ba57f 100644
--- a/drivers/regulator/lp3972.c
+++ b/drivers/regulator/lp3972.c
@@ -537,7 +537,7 @@ static int lp3972_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id lp3972_i2c_id[] = {
- { "lp3972" },
+ { .name = "lp3972" },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp3972_i2c_id);
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c
index 942f37082cb1..779df653338a 100644
--- a/drivers/regulator/lp872x.c
+++ b/drivers/regulator/lp872x.c
@@ -796,24 +796,24 @@ static const struct regmap_config lp872x_regmap_config = {
#define LP872X_VALID_OPMODE (REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL)
static struct of_regulator_match lp8720_matches[] = {
- { .name = "ldo1", .driver_data = (void *)LP8720_ID_LDO1, },
- { .name = "ldo2", .driver_data = (void *)LP8720_ID_LDO2, },
- { .name = "ldo3", .driver_data = (void *)LP8720_ID_LDO3, },
- { .name = "ldo4", .driver_data = (void *)LP8720_ID_LDO4, },
- { .name = "ldo5", .driver_data = (void *)LP8720_ID_LDO5, },
- { .name = "buck", .driver_data = (void *)LP8720_ID_BUCK, },
+ { .name = "ldo1", .driver_data = (void *)LP8720_ID_LDO1 },
+ { .name = "ldo2", .driver_data = (void *)LP8720_ID_LDO2 },
+ { .name = "ldo3", .driver_data = (void *)LP8720_ID_LDO3 },
+ { .name = "ldo4", .driver_data = (void *)LP8720_ID_LDO4 },
+ { .name = "ldo5", .driver_data = (void *)LP8720_ID_LDO5 },
+ { .name = "buck", .driver_data = (void *)LP8720_ID_BUCK },
};
static struct of_regulator_match lp8725_matches[] = {
- { .name = "ldo1", .driver_data = (void *)LP8725_ID_LDO1, },
- { .name = "ldo2", .driver_data = (void *)LP8725_ID_LDO2, },
- { .name = "ldo3", .driver_data = (void *)LP8725_ID_LDO3, },
- { .name = "ldo4", .driver_data = (void *)LP8725_ID_LDO4, },
- { .name = "ldo5", .driver_data = (void *)LP8725_ID_LDO5, },
- { .name = "lilo1", .driver_data = (void *)LP8725_ID_LILO1, },
- { .name = "lilo2", .driver_data = (void *)LP8725_ID_LILO2, },
- { .name = "buck1", .driver_data = (void *)LP8725_ID_BUCK1, },
- { .name = "buck2", .driver_data = (void *)LP8725_ID_BUCK2, },
+ { .name = "ldo1", .driver_data = (void *)LP8725_ID_LDO1 },
+ { .name = "ldo2", .driver_data = (void *)LP8725_ID_LDO2 },
+ { .name = "ldo3", .driver_data = (void *)LP8725_ID_LDO3 },
+ { .name = "ldo4", .driver_data = (void *)LP8725_ID_LDO4 },
+ { .name = "ldo5", .driver_data = (void *)LP8725_ID_LDO5 },
+ { .name = "lilo1", .driver_data = (void *)LP8725_ID_LILO1 },
+ { .name = "lilo2", .driver_data = (void *)LP8725_ID_LILO2 },
+ { .name = "buck1", .driver_data = (void *)LP8725_ID_BUCK1 },
+ { .name = "buck2", .driver_data = (void *)LP8725_ID_BUCK2 },
};
static struct lp872x_platform_data
@@ -935,8 +935,8 @@ static const struct of_device_id lp872x_dt_ids[] __maybe_unused = {
MODULE_DEVICE_TABLE(of, lp872x_dt_ids);
static const struct i2c_device_id lp872x_ids[] = {
- {"lp8720", LP8720},
- {"lp8725", LP8725},
+ { .name = "lp8720", .driver_data = LP8720 },
+ { .name = "lp8725", .driver_data = LP8725 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp872x_ids);
diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c
index 5509bee49bda..632320ba1800 100644
--- a/drivers/regulator/lp8755.c
+++ b/drivers/regulator/lp8755.c
@@ -430,8 +430,8 @@ static void lp8755_remove(struct i2c_client *client)
}
static const struct i2c_device_id lp8755_id[] = {
- { LP8755_NAME },
- {}
+ { .name = LP8755_NAME },
+ { }
};
MODULE_DEVICE_TABLE(i2c, lp8755_id);
diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c
index 3f70c2225dba..8bae5d8aeaf4 100644
--- a/drivers/regulator/ltc3589.c
+++ b/drivers/regulator/ltc3589.c
@@ -445,9 +445,9 @@ static const struct ltc3589_info ltc3589_12_info = {
};
static const struct i2c_device_id ltc3589_i2c_id[] = {
- { "ltc3589", (kernel_ulong_t)<c3589_info },
- { "ltc3589-1", (kernel_ulong_t)<c3589_12_info },
- { "ltc3589-2", (kernel_ulong_t)<c3589_12_info },
+ { .name = "ltc3589", .driver_data = (kernel_ulong_t)<c3589_info },
+ { .name = "ltc3589-1", .driver_data = (kernel_ulong_t)<c3589_12_info },
+ { .name = "ltc3589-2", .driver_data = (kernel_ulong_t)<c3589_12_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc3589_i2c_id);
diff --git a/drivers/regulator/ltc3676.c b/drivers/regulator/ltc3676.c
index 73d511eb1c1d..597d20a200d7 100644
--- a/drivers/regulator/ltc3676.c
+++ b/drivers/regulator/ltc3676.c
@@ -357,7 +357,7 @@ static int ltc3676_regulator_probe(struct i2c_client *client)
}
static const struct i2c_device_id ltc3676_i2c_id[] = {
- { "ltc3676" },
+ { .name = "ltc3676" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc3676_i2c_id);
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index 4242fbb7b147..e5cbc09c2d39 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -276,7 +276,7 @@ static int max1586_pmic_probe(struct i2c_client *client)
}
static const struct i2c_device_id max1586_id[] = {
- { "max1586" },
+ { .name = "max1586" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max1586_id);
diff --git a/drivers/regulator/max20086-regulator.c b/drivers/regulator/max20086-regulator.c
index fcdd2d0317a5..92594b2915f3 100644
--- a/drivers/regulator/max20086-regulator.c
+++ b/drivers/regulator/max20086-regulator.c
@@ -301,10 +301,10 @@ static const struct max20086_chip_info max20089_chip_info = {
};
static const struct i2c_device_id max20086_i2c_id[] = {
- { "max20086", (kernel_ulong_t)&max20086_chip_info },
- { "max20087", (kernel_ulong_t)&max20087_chip_info },
- { "max20088", (kernel_ulong_t)&max20088_chip_info },
- { "max20089", (kernel_ulong_t)&max20089_chip_info },
+ { .name = "max20086", .driver_data = (kernel_ulong_t)&max20086_chip_info },
+ { .name = "max20087", .driver_data = (kernel_ulong_t)&max20087_chip_info },
+ { .name = "max20088", .driver_data = (kernel_ulong_t)&max20088_chip_info },
+ { .name = "max20089", .driver_data = (kernel_ulong_t)&max20089_chip_info },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, max20086_i2c_id);
diff --git a/drivers/regulator/max20411-regulator.c b/drivers/regulator/max20411-regulator.c
index 6c0ebb970e90..ac7a9aa014aa 100644
--- a/drivers/regulator/max20411-regulator.c
+++ b/drivers/regulator/max20411-regulator.c
@@ -145,7 +145,7 @@ static const struct of_device_id of_max20411_match_tbl[] = {
MODULE_DEVICE_TABLE(of, of_max20411_match_tbl);
static const struct i2c_device_id max20411_id[] = {
- { "max20411" },
+ { .name = "max20411" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max20411_id);
diff --git a/drivers/regulator/max77503-regulator.c b/drivers/regulator/max77503-regulator.c
index c7c94e868fc1..1cae846f96d0 100644
--- a/drivers/regulator/max77503-regulator.c
+++ b/drivers/regulator/max77503-regulator.c
@@ -107,7 +107,7 @@ static const struct of_device_id of_max77503_match_tbl[] = {
MODULE_DEVICE_TABLE(of, of_max77503_match_tbl);
static const struct i2c_device_id max77503_regulator_id[] = {
- {"max77503"},
+ { .name = "max77503" },
{ }
};
diff --git a/drivers/regulator/max77675-regulator.c b/drivers/regulator/max77675-regulator.c
index 57350526afd7..ebea08ddf4b8 100644
--- a/drivers/regulator/max77675-regulator.c
+++ b/drivers/regulator/max77675-regulator.c
@@ -1029,7 +1029,7 @@ static int max77675_regulator_probe(struct i2c_client *client)
}
static const struct i2c_device_id max77675_i2c_id[] = {
- { "max77675" },
+ { .name = "max77675" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max77675_i2c_id);
diff --git a/drivers/regulator/max77826-regulator.c b/drivers/regulator/max77826-regulator.c
index 310bc8ee7af8..8b60a9fcab44 100644
--- a/drivers/regulator/max77826-regulator.c
+++ b/drivers/regulator/max77826-regulator.c
@@ -278,7 +278,7 @@ static const struct of_device_id __maybe_unused max77826_of_match[] = {
MODULE_DEVICE_TABLE(of, max77826_of_match);
static const struct i2c_device_id max77826_id[] = {
- { "max77826-regulator" },
+ { .name = "max77826-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, max77826_id);
diff --git a/drivers/regulator/max77838-regulator.c b/drivers/regulator/max77838-regulator.c
index 9faddbfd25fd..765756fdcf6e 100644
--- a/drivers/regulator/max77838-regulator.c
+++ b/drivers/regulator/max77838-regulator.c
@@ -200,7 +200,7 @@ static const struct of_device_id __maybe_unused max77838_of_match[] = {
MODULE_DEVICE_TABLE(of, max77838_of_match);
static const struct i2c_device_id max77838_id[] = {
- { "max77838-regulator" },
+ { .name = "max77838-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, max77838_id);
diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max77857-regulator.c
index 1216cc3a6f72..f1410f845653 100644
--- a/drivers/regulator/max77857-regulator.c
+++ b/drivers/regulator/max77857-regulator.c
@@ -428,10 +428,10 @@ static int max77857_probe(struct i2c_client *client)
}
static const struct i2c_device_id max77857_id[] = {
- { "max77831", ID_MAX77831 },
- { "max77857", ID_MAX77857 },
- { "max77859", ID_MAX77859 },
- { "max77859a", ID_MAX77859A },
+ { .name = "max77831", .driver_data = ID_MAX77831 },
+ { .name = "max77857", .driver_data = ID_MAX77857 },
+ { .name = "max77859", .driver_data = ID_MAX77859 },
+ { .name = "max77859a", .driver_data = ID_MAX77859A },
{ }
};
MODULE_DEVICE_TABLE(i2c, max77857_id);
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c
index f57c588bcf28..2d17405242e7 100644
--- a/drivers/regulator/max8649.c
+++ b/drivers/regulator/max8649.c
@@ -240,7 +240,7 @@ static int max8649_regulator_probe(struct i2c_client *client)
}
static const struct i2c_device_id max8649_id[] = {
- { "max8649" },
+ { .name = "max8649" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max8649_id);
diff --git a/drivers/regulator/max8893.c b/drivers/regulator/max8893.c
index 5a90633d8536..7a0e44a16d49 100644
--- a/drivers/regulator/max8893.c
+++ b/drivers/regulator/max8893.c
@@ -162,7 +162,7 @@ MODULE_DEVICE_TABLE(of, max8893_dt_match);
#endif
static const struct i2c_device_id max8893_ids[] = {
- { "max8893" },
+ { .name = "max8893" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max8893_ids);
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c
index 1f94315bfb02..f8b91a5701f3 100644
--- a/drivers/regulator/max8952.c
+++ b/drivers/regulator/max8952.c
@@ -307,7 +307,7 @@ static int max8952_pmic_probe(struct i2c_client *client)
}
static const struct i2c_device_id max8952_ids[] = {
- { "max8952" },
+ { .name = "max8952" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max8952_ids);
diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
index b34ae0bbba6f..89fd79d446f7 100644
--- a/drivers/regulator/mcp16502.c
+++ b/drivers/regulator/mcp16502.c
@@ -578,7 +578,7 @@ static const struct dev_pm_ops mcp16502_pm_ops = {
};
#endif
static const struct i2c_device_id mcp16502_i2c_id[] = {
- { "mcp16502" },
+ { .name = "mcp16502" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mcp16502_i2c_id);
diff --git a/drivers/regulator/mp5416.c b/drivers/regulator/mp5416.c
index e6794190cb68..2948635b1b9f 100644
--- a/drivers/regulator/mp5416.c
+++ b/drivers/regulator/mp5416.c
@@ -228,9 +228,9 @@ static const struct of_device_id mp5416_of_match[] = {
MODULE_DEVICE_TABLE(of, mp5416_of_match);
static const struct i2c_device_id mp5416_id[] = {
- { "mp5416", (kernel_ulong_t)&mp5416_regulators_desc },
- { "mp5496", (kernel_ulong_t)&mp5496_regulators_desc },
- {}
+ { .name = "mp5416", .driver_data = (kernel_ulong_t)&mp5416_regulators_desc },
+ { .name = "mp5496", .driver_data = (kernel_ulong_t)&mp5496_regulators_desc },
+ { }
};
MODULE_DEVICE_TABLE(i2c, mp5416_id);
diff --git a/drivers/regulator/mp8859.c b/drivers/regulator/mp8859.c
index ab105ffd6a2e..9a708e826d93 100644
--- a/drivers/regulator/mp8859.c
+++ b/drivers/regulator/mp8859.c
@@ -386,8 +386,8 @@ static const struct of_device_id mp8859_dt_id[] __maybe_unused = {
MODULE_DEVICE_TABLE(of, mp8859_dt_id);
static const struct i2c_device_id mp8859_i2c_id[] = {
- { "mp8859", },
- { },
+ { .name = "mp8859" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, mp8859_i2c_id);
diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c
index 9ad16b04c913..e0b62bc02a1e 100644
--- a/drivers/regulator/mp886x.c
+++ b/drivers/regulator/mp886x.c
@@ -348,9 +348,9 @@ static const struct of_device_id mp886x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, mp886x_dt_ids);
static const struct i2c_device_id mp886x_id[] = {
- { "mp8867", (kernel_ulong_t)&mp8867_ci },
- { "mp8869", (kernel_ulong_t)&mp8869_ci },
- { },
+ { .name = "mp8867", .driver_data = (kernel_ulong_t)&mp8867_ci },
+ { .name = "mp8869", .driver_data = (kernel_ulong_t)&mp8869_ci },
+ { }
};
MODULE_DEVICE_TABLE(i2c, mp886x_id);
diff --git a/drivers/regulator/mpq7920.c b/drivers/regulator/mpq7920.c
index a670e09891e7..0cbc17deb1d1 100644
--- a/drivers/regulator/mpq7920.c
+++ b/drivers/regulator/mpq7920.c
@@ -309,8 +309,8 @@ static const struct of_device_id mpq7920_of_match[] = {
MODULE_DEVICE_TABLE(of, mpq7920_of_match);
static const struct i2c_device_id mpq7920_id[] = {
- { "mpq7920", },
- { },
+ { .name = "mpq7920" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, mpq7920_id);
diff --git a/drivers/regulator/mt6311-regulator.c b/drivers/regulator/mt6311-regulator.c
index 2ebc1c0b5e6f..1d457d1fdf23 100644
--- a/drivers/regulator/mt6311-regulator.c
+++ b/drivers/regulator/mt6311-regulator.c
@@ -133,8 +133,8 @@ static int mt6311_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id mt6311_i2c_id[] = {
- { "mt6311" },
- {}
+ { .name = "mt6311" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, mt6311_i2c_id);
diff --git a/drivers/regulator/pf530x-regulator.c b/drivers/regulator/pf530x-regulator.c
index ef3d5bb784cd..8ad1cbbd7a8c 100644
--- a/drivers/regulator/pf530x-regulator.c
+++ b/drivers/regulator/pf530x-regulator.c
@@ -353,9 +353,9 @@ static const struct of_device_id pf530x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pf530x_dt_ids);
static const struct i2c_device_id pf530x_i2c_id[] = {
- { "pf5300" },
- { "pf5301" },
- { "pf5302" },
+ { .name = "pf5300" },
+ { .name = "pf5301" },
+ { .name = "pf5302" },
{ }
};
MODULE_DEVICE_TABLE(i2c, pf530x_i2c_id);
diff --git a/drivers/regulator/pf8x00-regulator.c b/drivers/regulator/pf8x00-regulator.c
index ea3611de42b4..c938b4632ef1 100644
--- a/drivers/regulator/pf8x00-regulator.c
+++ b/drivers/regulator/pf8x00-regulator.c
@@ -596,10 +596,10 @@ static const struct of_device_id pf8x00_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pf8x00_dt_ids);
static const struct i2c_device_id pf8x00_i2c_id[] = {
- { "pf8100" },
- { "pf8121a" },
- { "pf8200" },
- {}
+ { .name = "pf8100" },
+ { .name = "pf8121a" },
+ { .name = "pf8200" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, pf8x00_i2c_id);
diff --git a/drivers/regulator/pv88060-regulator.c b/drivers/regulator/pv88060-regulator.c
index ae1c4b9daaa1..375d9e759c47 100644
--- a/drivers/regulator/pv88060-regulator.c
+++ b/drivers/regulator/pv88060-regulator.c
@@ -360,8 +360,8 @@ static int pv88060_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id pv88060_i2c_id[] = {
- { "pv88060" },
- {}
+ { .name = "pv88060" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, pv88060_i2c_id);
diff --git a/drivers/regulator/pv88080-regulator.c b/drivers/regulator/pv88080-regulator.c
index 9fe539a34786..3dc48d059791 100644
--- a/drivers/regulator/pv88080-regulator.c
+++ b/drivers/regulator/pv88080-regulator.c
@@ -523,10 +523,10 @@ static const struct of_device_id pv88080_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pv88080_dt_ids);
static const struct i2c_device_id pv88080_i2c_id[] = {
- { "pv88080", (kernel_ulong_t)&pv88080_aa_regs },
- { "pv88080-aa", (kernel_ulong_t)&pv88080_aa_regs },
- { "pv88080-ba", (kernel_ulong_t)&pv88080_ba_regs },
- {}
+ { .name = "pv88080", .driver_data = (kernel_ulong_t)&pv88080_aa_regs },
+ { .name = "pv88080-aa", .driver_data = (kernel_ulong_t)&pv88080_aa_regs },
+ { .name = "pv88080-ba", .driver_data = (kernel_ulong_t)&pv88080_ba_regs },
+ { }
};
MODULE_DEVICE_TABLE(i2c, pv88080_i2c_id);
diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c
index 3c48757bbbda..ca5eeb5dfe62 100644
--- a/drivers/regulator/pv88090-regulator.c
+++ b/drivers/regulator/pv88090-regulator.c
@@ -381,8 +381,8 @@ static int pv88090_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id pv88090_i2c_id[] = {
- { "pv88090" },
- {}
+ { .name = "pv88090" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, pv88090_i2c_id);
diff --git a/drivers/regulator/slg51000-regulator.c b/drivers/regulator/slg51000-regulator.c
index 3bbd4a29e6d3..d682764cdbf8 100644
--- a/drivers/regulator/slg51000-regulator.c
+++ b/drivers/regulator/slg51000-regulator.c
@@ -497,8 +497,8 @@ static int slg51000_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id slg51000_i2c_id[] = {
- { "slg51000" },
- {}
+ { .name = "slg51000" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, slg51000_i2c_id);
diff --git a/drivers/regulator/sy8106a-regulator.c b/drivers/regulator/sy8106a-regulator.c
index d79a4cc25a0d..b2b835c60262 100644
--- a/drivers/regulator/sy8106a-regulator.c
+++ b/drivers/regulator/sy8106a-regulator.c
@@ -130,7 +130,7 @@ static const struct of_device_id sy8106a_i2c_of_match[] = {
MODULE_DEVICE_TABLE(of, sy8106a_i2c_of_match);
static const struct i2c_device_id sy8106a_i2c_id[] = {
- { "sy8106a" },
+ { .name = "sy8106a" },
{ }
};
MODULE_DEVICE_TABLE(i2c, sy8106a_i2c_id);
diff --git a/drivers/regulator/sy8824x.c b/drivers/regulator/sy8824x.c
index 5bec84db25f1..3f07e7da90cb 100644
--- a/drivers/regulator/sy8824x.c
+++ b/drivers/regulator/sy8824x.c
@@ -213,10 +213,10 @@ static const struct of_device_id sy8824_dt_ids[] = {
MODULE_DEVICE_TABLE(of, sy8824_dt_ids);
static const struct i2c_device_id sy8824_id[] = {
- { "sy8824c", (kernel_ulong_t)&sy8824c_cfg },
- { "sy8824e", (kernel_ulong_t)&sy8824e_cfg },
- { "sy20276", (kernel_ulong_t)&sy20276_cfg },
- { "sy20278", (kernel_ulong_t)&sy20278_cfg },
+ { .name = "sy8824c", .driver_data = (kernel_ulong_t)&sy8824c_cfg },
+ { .name = "sy8824e", .driver_data = (kernel_ulong_t)&sy8824e_cfg },
+ { .name = "sy20276", .driver_data = (kernel_ulong_t)&sy20276_cfg },
+ { .name = "sy20278", .driver_data = (kernel_ulong_t)&sy20278_cfg },
{ }
};
MODULE_DEVICE_TABLE(i2c, sy8824_id);
diff --git a/drivers/regulator/sy8827n.c b/drivers/regulator/sy8827n.c
index 0b811514782f..a1cac8cc3d96 100644
--- a/drivers/regulator/sy8827n.c
+++ b/drivers/regulator/sy8827n.c
@@ -180,8 +180,8 @@ static const struct of_device_id sy8827n_dt_ids[] = {
MODULE_DEVICE_TABLE(of, sy8827n_dt_ids);
static const struct i2c_device_id sy8827n_id[] = {
- { "sy8827n", },
- { },
+ { .name = "sy8827n" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, sy8827n_id);
diff --git a/drivers/regulator/tps6286x-regulator.c b/drivers/regulator/tps6286x-regulator.c
index e29aab06bf79..1ab53bee9f6e 100644
--- a/drivers/regulator/tps6286x-regulator.c
+++ b/drivers/regulator/tps6286x-regulator.c
@@ -145,11 +145,11 @@ static int tps6286x_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id tps6286x_i2c_id[] = {
- { "tps62864" },
- { "tps62866" },
- { "tps62868" },
- { "tps62869" },
- {}
+ { .name = "tps62864" },
+ { .name = "tps62866" },
+ { .name = "tps62868" },
+ { .name = "tps62869" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, tps6286x_i2c_id);
diff --git a/drivers/regulator/tps6287x-regulator.c b/drivers/regulator/tps6287x-regulator.c
index 7b7d3ae39206..c0bc4a6192c4 100644
--- a/drivers/regulator/tps6287x-regulator.c
+++ b/drivers/regulator/tps6287x-regulator.c
@@ -229,11 +229,11 @@ static const struct of_device_id tps6287x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, tps6287x_dt_ids);
static const struct i2c_device_id tps6287x_i2c_id[] = {
- { "tps62870" },
- { "tps62871" },
- { "tps62872" },
- { "tps62873" },
- {}
+ { .name = "tps62870" },
+ { .name = "tps62871" },
+ { .name = "tps62872" },
+ { .name = "tps62873" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, tps6287x_i2c_id);
--
2.47.3
^ permalink raw reply related
* [PATCH v2 0/2] regulator: Rework i2c_device_id initialisation
From: Uwe Kleine-König (The Capable Hub) @ 2026-05-19 9:57 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown
Cc: Laurent Pinchart, Woodrow Douglass, linux-kernel,
Michael Hennerich, Support Opensource, Ivaylo Ivanov,
Claudiu Beznea, Andrei Simion, Saravanan Sekar, Matthias Brugger,
AngeloGioacchino Del Regno, Jagan Teki, Icenowy Zheng,
linux-arm-kernel, linux-mediatek
Hello,
Laurent pointed out one driver in my v1
(https://lore.kernel.org/linux-kernel/20260515103150.164887-2-u.kleine-koenig@baylibre.com)
that doesn't actually make use of its .driver_data. I found a second
while adapting the patch set. So this v2 consists of a first patch that
drops these driver data assigments and a second to convert to named
initializers which is mostly the patch sent before.
It might be too conservative, but I didn't apply Laurent's conditional
Reviewed-by tag as my change is a bit different than anticipated.
Best regards
Uwe
Uwe Kleine-König (The Capable Hub) (2):
regulator: Drop unused i2c driver data
regulator: Use named initializers for arrays of i2c_device_data
drivers/regulator/88pg86x.c | 4 +--
drivers/regulator/ad5398.c | 4 +--
drivers/regulator/da9121-regulator.c | 20 +++++++--------
drivers/regulator/da9210-regulator.c | 4 +--
drivers/regulator/da9211-regulator.c | 18 +++++++-------
drivers/regulator/fan53880.c | 4 +--
drivers/regulator/isl9305.c | 4 +--
drivers/regulator/lp3971.c | 2 +-
drivers/regulator/lp3972.c | 2 +-
drivers/regulator/lp872x.c | 34 +++++++++++++-------------
drivers/regulator/lp8755.c | 4 +--
drivers/regulator/ltc3589.c | 6 ++---
drivers/regulator/ltc3676.c | 2 +-
drivers/regulator/max1586.c | 2 +-
drivers/regulator/max20086-regulator.c | 8 +++---
drivers/regulator/max20411-regulator.c | 2 +-
drivers/regulator/max77503-regulator.c | 2 +-
drivers/regulator/max77675-regulator.c | 2 +-
drivers/regulator/max77826-regulator.c | 2 +-
drivers/regulator/max77838-regulator.c | 2 +-
drivers/regulator/max77857-regulator.c | 8 +++---
drivers/regulator/max8649.c | 2 +-
drivers/regulator/max8893.c | 2 +-
drivers/regulator/max8952.c | 2 +-
drivers/regulator/mcp16502.c | 2 +-
drivers/regulator/mp5416.c | 6 ++---
drivers/regulator/mp8859.c | 4 +--
drivers/regulator/mp886x.c | 6 ++---
drivers/regulator/mpq7920.c | 4 +--
drivers/regulator/mt6311-regulator.c | 4 +--
drivers/regulator/pf530x-regulator.c | 8 +++---
drivers/regulator/pf8x00-regulator.c | 8 +++---
drivers/regulator/pv88060-regulator.c | 4 +--
drivers/regulator/pv88080-regulator.c | 8 +++---
drivers/regulator/pv88090-regulator.c | 4 +--
drivers/regulator/slg51000-regulator.c | 4 +--
drivers/regulator/sy8106a-regulator.c | 2 +-
drivers/regulator/sy8824x.c | 8 +++---
drivers/regulator/sy8827n.c | 4 +--
drivers/regulator/tps6286x-regulator.c | 10 ++++----
drivers/regulator/tps6287x-regulator.c | 10 ++++----
41 files changed, 119 insertions(+), 119 deletions(-)
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
--
2.47.3
^ permalink raw reply
* Re: [Linaro-mm-sig] Re: [PATCH 4/8] drm/panthor: Add support for protected memory allocation in panthor
From: Maxime Ripard @ 2026-05-19 9:52 UTC (permalink / raw)
To: Boris Brezillon
Cc: Chia-I Wu, Liviu Dudau, Marcin Ślusarz, Ketil Johnsen,
David Airlie, Simona Vetter, Maarten Lankhorst, Thomas Zimmermann,
Jonathan Corbet, Shuah Khan, Sumit Semwal, Benjamin Gaignard,
Brian Starkey, John Stultz, T.J. Mercier, Christian König,
Steven Price, Daniel Almeida, Alice Ryhl, Matthias Brugger,
AngeloGioacchino Del Regno, dri-devel, linux-doc, linux-kernel,
linux-media, linaro-mm-sig, linux-arm-kernel, linux-mediatek,
Florent Tomasin, nd
In-Reply-To: <20260518091650.5a7a4f4a@fedora>
[-- Attachment #1: Type: text/plain, Size: 3983 bytes --]
Hi Boris,
On Mon, May 18, 2026 at 09:16:50AM +0200, Boris Brezillon wrote:
> On Wed, 13 May 2026 12:31:32 -0700
> Chia-I Wu <olvaffe@gmail.com> wrote:
>
> > On Tue, May 12, 2026 at 8:39 AM Liviu Dudau <liviu.dudau@arm.com> wrote:
> > >
> > > On Tue, May 12, 2026 at 04:11:11PM +0200, Boris Brezillon wrote:
> > > > On Tue, 12 May 2026 14:47:27 +0100
> > > > Liviu Dudau <liviu.dudau@arm.com> wrote:
> > > >
> > > > > On Thu, May 07, 2026 at 01:53:56PM +0200, Boris Brezillon wrote:
> > > > > > On Thu, 7 May 2026 11:02:26 +0200
> > > > > > Marcin Ślusarz <marcin.slusarz@arm.com> wrote:
> > > > > >
> > > > > > > On Tue, May 05, 2026 at 06:15:23PM +0200, Boris Brezillon wrote:
> > > > > > > > > @@ -277,9 +286,21 @@ int panthor_device_init(struct panthor_device *ptdev)
> > > > > > > > > return ret;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > + /* If a protected heap name is specified but not found, defer the probe until created */
> > > > > > > > > + if (protected_heap_name && strlen(protected_heap_name)) {
> > > > > > > >
> > > > > > > > Do we really need this strlen() > 0? Won't dma_heap_find() fail is the
> > > > > > > > name is "" already?
> > > > > > >
> > > > > > > If dma_heap_find() will fail, then the whole probe with fail too.
> > > > > > > This check prevents that.
> > > > > >
> > > > > > Yeah, that's also a questionable design choice. I mean, we can
> > > > > > currently probe and boot the FW even though we never setup the
> > > > > > protected FW sections, so why should we defer the probe here? Can't we
> > > > > > just retry the next time a group with the protected bit is created and
> > > > > > fail if we can find a protected heap?
> > > > >
> > > > > The problem we have with the current firmware is that it does a number of setup steps at "boot"
> > > > > time only. One of the steps is preparing its internal structures for when it enters protected
> > > > > mode and it stores them in the buffer passed in at firmware loading. We cannot later run the
> > > > > process when we have a group with protected mode set.
> > > >
> > > > No, but we can force a full/slow reset and have that thing
> > > > re-initialized, can't we? I mean, that's basically what we do when a
> > > > fast reset fails: we re-initialize all the sections and reset again, at
> > > > which point the FW should start from a fresh state, and be able to
> > > > properly initialize the protected-related stuff if protected sections
> > > > are populated. Am I missing something?
> > >
> > > Right, we can do that. For some reason I keep associating the reset with the
> > > error handling and not with "normal" operations.
> > I kind of hope we end up with either
> >
> > - panthor knows the exact heap to use and fails with EPROBE_DEFER if
> > the heap is missing, or
> > - panthor gets a dma-buf from userspace and does the full reset
> > - userspace also needs to provide a dma-buf for each protected
> > group for the suspend buffer
> >
> > than something in-between. The latter is more ad-hoc and basically
> > kicks the issue to the userspace.
>
> Indeed, the second option is more ad-hoc, but when you think about it,
> userspace has to have this knowledge, because it needs to know the
> dma-heap to use for buffer allocation that cross a device boundary
> anyway. Think about frames produced by a video decoder, and composited
> by the GPU into a protected scanout buffer that's passed to the KMS
> device. Why would the GPU driver be source of truth when it comes to
> choosing the heap to use to allocate protected buffers for the video
> decoder or those used for the display?
Just fyi, the trend is to go to devices listing the heaps userspace
should allocate from and/or using the heaps internally to allocate their
buffers, so that last part is where we're headed, and feels totally
reasonable to me.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply
* Re: [PATCH] ASoC: mediatek: mt8196: Fix probe resource cleanup
From: Mark Brown @ 2026-05-18 16:25 UTC (permalink / raw)
To: Liam Girdwood, Takashi Iwai, Jaroslav Kysela, Matthias Brugger,
AngeloGioacchino Del Regno, Darren Ye, Cyril Chao,
Cássio Gabriel
Cc: linux-sound, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20260517-asoc-mt8196-probe-cleanup-v1-1-a5d26949d7fe@gmail.com>
On Sun, 17 May 2026 23:41:07 -0300, Cássio Gabriel wrote:
> ASoC: mediatek: mt8196: Fix probe resource cleanup
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.2
Thanks!
[1/1] ASoC: mediatek: mt8196: Fix probe resource cleanup
https://git.kernel.org/broonie/sound/c/e38353138a09
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ 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