Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [EXT] Re: [PATCH v2] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Daniel Baluta @ 2026-04-16  6:04 UTC (permalink / raw)
  To: Zhipeng Wang, Marco Felsch
  Cc: ulfh@kernel.org, Frank Li, s.hauer@pengutronix.de,
	imx@lists.linux.dev, linux-pm@vger.kernel.org, Xuegang Liu,
	Jindong Yue, linux-kernel@vger.kernel.org, kernel@pengutronix.de,
	festevam@gmail.com, linux-arm-kernel@lists.infradead.org
In-Reply-To: <AMBPR04MB123344C1F802528A10CEA7FADEB252@AMBPR04MB12334.eurprd04.prod.outlook.com>

On 4/14/26 04:59, Zhipeng Wang wrote:
>  > On 26-04-13, Zhipeng Wang wrote:
>>> Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate to
>>> allow building as loadable modules.
>> Out of curiosity, why do you want to have a PM driver to be buildable as
>> module?
>>
>> Regards,
>>   Marco
>>
> Hi Marco,
>
> Thank you for your question.
>
> The primary motivation is to support Google's GKI (Generic Kernel Image)
> requirement for Android devices.
>
> GKI separates the kernel into two parts:
> 1. A unified kernel image (GKI) that is common across all Android devices
> 2. Vendor-specific drivers that must be built as loadable modules
>
> Under the GKI architecture, SoC-specific drivers like IMX8M/IMX9 BLK_CTRL
> cannot be built into the core kernel image. Instead, they must be loadable
> modules that vendors can ship separately. This allows:
>
> - A single kernel binary to support multiple hardware platforms
> - Vendors to update their drivers independently without rebuilding the entire kernel
> - Better compliance with Android's kernel update and security policies
>
Can you please add the below line in the commit message?
> For i.MX8M/i.MX9 devices running Android with GKI kernels, the BLK_CTRL
> drivers need to be loaded as modules during boot. Without tristate support,
> these devices cannot properly initialize their power domains, making them
> non-functional under GKI.




^ permalink raw reply

* Re: [PATCH v2 2/3] dt-bindings: gpio: Add EIO GPIO compatible to gpio-zynq
From: Michal Simek @ 2026-04-16  5:58 UTC (permalink / raw)
  To: Conor Dooley, Shubhrajyoti Datta
  Cc: linux-kernel, git, shubhrajyoti.datta, Srinivas Neeli,
	Linus Walleij, Bartosz Golaszewski, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-gpio, devicetree,
	linux-arm-kernel
In-Reply-To: <20260415-rectal-visible-a8ccb534a176@spud>



On 4/15/26 17:01, Conor Dooley wrote:
> On Wed, Apr 15, 2026 at 04:26:27PM +0530, Shubhrajyoti Datta wrote:
>> EIO (Extended IO) is a GPIO block found on xa2ve3288 silicon..
> 
> 
> Why does the compatible have a "1.0" when it is in silicon?

Sorry not following what the problem is. Yes this is hard block in silicon
and it is silicon v1.

> Why doesn't the compatible contain "xa2ve3288"?

This unit can be used on different silicons too.

> Why is this device not compatible with existing ones, since
> gpio-lines-names appears to be the sole difference?

There is no way how to detect gpio width.
Pretty much soc_device_match() to some extend could be use to detect which 
silicon it runs but on this particular one you have 3 gpio controllers described 
by this binding (pmc, versal and eio).

Thanks,
Michal



^ permalink raw reply

* Re: [PATCH v3] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Daniel Baluta @ 2026-04-16  6:01 UTC (permalink / raw)
  To: Zhipeng Wang, ulfh, Frank.Li, s.hauer
  Cc: kernel, festevam, linux-pm, imx, linux-arm-kernel, linux-kernel,
	xuegang.liu, jindong.yue
In-Reply-To: <20260416015605.3536244-1-zhipeng.wang_1@nxp.com>

On 4/16/26 04:56, Zhipeng Wang wrote:
> Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate
> to allow building as loadable modules.
>
> Add prompt strings to make these options visible and configurable
> in menuconfig, keeping them enabled by default on appropriate platforms.
>
> Also remove the IMX_GPCV2_PM_DOMAINS dependency from IMX9_BLK_CTRL.
> This dependency was incorrect from the beginning because i.MX93 uses a
> different power domain architecture compared to i.MX8M series:
>
> - i.MX8M uses GPCv2 (General Power Controller v2) for power domain
>   management, hence IMX8M_BLK_CTRL correctly depends on it.
>
> - i.MX93 uses BLK_CTRL directly without GPCv2. The hardware doesn't
>   have GPCv2 at all.
>
> Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
>
> ---

Please always add a change log here to help reviewers.

Change since v2:

* fixed typo reported by Frank




^ permalink raw reply

* Re: [PATCH v8 08/10] ASoC: mediatek: mt8196: add platform driver
From: Cyril Chao (钞悦) @ 2026-04-16  5:53 UTC (permalink / raw)
  To: broonie@kernel.org
  Cc: linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org,
	devicetree@vger.kernel.org, Darren Ye (叶飞),
	linux-sound@vger.kernel.org, conor+dt@kernel.org, tiwai@suse.com,
	robh@kernel.org, lgirdwood@gmail.com,
	linux-arm-kernel@lists.infradead.org,
	Project_Global_Chrome_Upstream_Group, matthias.bgg@gmail.com,
	krzk+dt@kernel.org, perex@perex.cz, AngeloGioacchino Del Regno
In-Reply-To: <892468cc-7eb4-411e-b91b-f14789d8da0c@sirena.org.uk>

Thank you for your assistance in reviewing. Could you please also
review the modifications in the diff? If everything is okay, I will
include them in v9 in the next update.


diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c
b/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c
index 3d3174cd8efb..ff7aa89e4779 100644
--- a/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c
+++ b/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c
@@ -90,9 +90,20 @@ static int mt8196_set_cm(struct mtk_base_afe *afe,
int id,
 	struct mt8196_afe_private *afe_priv = afe->platform_priv;
 	unsigned int rate = afe_priv->cm_rate[id];
 	unsigned int rate_val = mt8196_rate_transform(afe->dev, rate);
-	unsigned int update_val = update ? ((((26000000 / rate) - 10) /
(ch / 2)) - 1) : 0x64;
+	unsigned int ch_pair = ch / 2;
+	unsigned int update_val;
 	int reg = AFE_CM0_CON0 + 0x10 * id;
 
+	if (update) {
+		if (ch_pair == 0) {
+			dev_err(afe->dev, "CM%d: invalid channel count
%u\n", id, ch);
+			return -EINVAL;
+		}
+		update_val = (26000000 / rate - 10) / ch_pair - 1;
+	} else {
+		update_val = 0x64;
+	}
+
 	dev_dbg(afe->dev, "CM%d, rate %d, update %d, swap %d, ch %d\n",
 		id, rate, update, swap, ch);
 
@@ -471,6 +482,7 @@ static int ul_cm0_event(struct snd_soc_dapm_widget
*w,
 	struct mtk_base_afe *afe =
snd_soc_component_get_drvdata(cmpnt);
 	struct mt8196_afe_private *afe_priv = afe->platform_priv;
 	unsigned int channels = afe_priv->cm_channels;
+	int ret;
 
 	dev_dbg(afe->dev, "event 0x%x, name %s, channels %u\n",
 		event, w->name, channels);
@@ -478,7 +490,9 @@ static int ul_cm0_event(struct snd_soc_dapm_widget
*w,
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		mt8196_enable_cm_bypass(afe, CM0, false);
-		mt8196_set_cm(afe, CM0, true, false, channels);
+		ret = mt8196_set_cm(afe, CM0, true, false, channels);
+		if (ret)
+			return ret;
 		regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
 				   PDN_CM0_MASK_SFT, 0 << PDN_CM0_SFT);
 		break;
@@ -502,6 +516,7 @@ static int ul_cm1_event(struct snd_soc_dapm_widget
*w,
 	struct mtk_base_afe *afe =
snd_soc_component_get_drvdata(cmpnt);
 	struct mt8196_afe_private *afe_priv = afe->platform_priv;
 	unsigned int channels = afe_priv->cm_channels;
+	int ret;
 
 	dev_dbg(afe->dev, "event 0x%x, name %s, channels %u\n",
 		event, w->name, channels);
@@ -509,7 +524,9 @@ static int ul_cm1_event(struct snd_soc_dapm_widget
*w,
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		mt8196_enable_cm_bypass(afe, CM1, false);
-		mt8196_set_cm(afe, CM1, true, false, channels);
+		ret = mt8196_set_cm(afe, CM1, true, false, channels);
+		if (ret)
+			return ret;
 		regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
 				   PDN_CM1_MASK_SFT, 0 << PDN_CM1_SFT);
 		break;
@@ -533,6 +550,7 @@ static int ul_cm2_event(struct snd_soc_dapm_widget
*w,
 	struct mtk_base_afe *afe =
snd_soc_component_get_drvdata(cmpnt);
 	struct mt8196_afe_private *afe_priv = afe->platform_priv;
 	unsigned int channels = afe_priv->cm_channels;
+	int ret;
 
 	dev_dbg(afe->dev, "event 0x%x, name %s, channels %u\n",
 		event, w->name, channels);
@@ -540,7 +558,9 @@ static int ul_cm2_event(struct snd_soc_dapm_widget
*w,
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		mt8196_enable_cm_bypass(afe, CM2, false);
-		mt8196_set_cm(afe, CM2, true, false, channels);
+		ret = mt8196_set_cm(afe, CM2, true, false, channels);
+		if (ret)
+			return ret;
 		regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
 				   PDN_CM2_MASK_SFT, 0 << PDN_CM2_SFT);
 		break;

Best Regards
Cyril Chao


On Fri, 2026-04-03 at 15:07 +0100, Mark Brown wrote:
> On Tue, Mar 24, 2026 at 09:56:49AM +0800, Cyril Chao wrote:
> 
> > +static int mt8196_set_cm(struct mtk_base_afe *afe, int id,
> > +			 bool update, bool swap, unsigned int ch)
> > +{
> > +	struct mt8196_afe_private *afe_priv = afe->platform_priv;
> > +	unsigned int rate = afe_priv->cm_rate[id];
> > +	unsigned int rate_val = mt8196_rate_transform(afe->dev, rate);
> > +	unsigned int update_val = update ? ((((26000000 / rate) - 10) /
> > (ch / 2)) - 1) : 0x64;
> > +	int reg = AFE_CM0_CON0 + 0x10 * id;
> 
> The driver looks like it supports mono so won't this trigger divide
> by
> zero?
> 
> Also please write normal conditional statements, it's much more
> leigible.

^ permalink raw reply related

* Re: [PATCH v5 04/12] coresight: etm4x: exclude ss_status from drvdata->config
From: Jie Gan @ 2026-04-16  5:42 UTC (permalink / raw)
  To: Yeoreum Yun, coresight, linux-arm-kernel, linux-kernel
  Cc: suzuki.poulose, mike.leach, james.clark, alexander.shishkin,
	leo.yan
In-Reply-To: <20260415165528.3369607-5-yeoreum.yun@arm.com>



On 4/16/2026 12:55 AM, Yeoreum Yun wrote:
> The purpose of TRCSSCSRn register is to show status of
> the corresponding Single-shot Comparator Control and input supports.
> That means writable field's purpose for reset or restore from idle status
> not for configuration.
> 
> Therefore, exclude ss_status from drvdata->config, move it to etm4x_caps
> and rename it to ss_smp.
> 
> This includes remove TRCSSCRn from configurable item and
> remove saving in etm4_disable_hw().
> 
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> ---
>   .../hwtracing/coresight/coresight-etm4x-cfg.c |  1 -
>   .../coresight/coresight-etm4x-core.c          | 19 ++++++-------------
>   .../coresight/coresight-etm4x-sysfs.c         |  7 ++-----
>   drivers/hwtracing/coresight/coresight-etm4x.h |  7 ++++++-
>   4 files changed, 14 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> index c302072b293a..d14d7c8a23e5 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> @@ -86,7 +86,6 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata,
>   		off_mask =  (offset & GENMASK(11, 5));
>   		do {
>   			CHECKREGIDX(TRCSSCCRn(0), ss_ctrl, idx, off_mask);
> -			CHECKREGIDX(TRCSSCSRn(0), ss_status, idx, off_mask);
>   			CHECKREGIDX(TRCSSPCICRn(0), ss_pe_cmp, idx, off_mask);
>   		} while (0);
>   	} else if ((offset >= TRCCIDCVRn(0)) && (offset <= TRCVMIDCVRn(7))) {
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index b2b092a76eb5..f55338a4989d 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -91,7 +91,7 @@ static bool etm4x_sspcicrn_present(struct etmv4_drvdata *drvdata, int n)
>   	const struct etmv4_caps *caps = &drvdata->caps;
>   
>   	return (n < caps->nr_ss_cmp) && caps->nr_pe_cmp &&
> -	       (drvdata->config.ss_status[n] & TRCSSCSRn_PC);
> +	       (caps->ss_cmp[n] & TRCSSCSRn_PC);
>   }
>   
>   u64 etm4x_sysreg_read(u32 offset, bool _relaxed, bool _64bit)
> @@ -573,11 +573,9 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
>   		etm4x_relaxed_write32(csa, config->res_ctrl[i], TRCRSCTLRn(i));
>   
>   	for (i = 0; i < caps->nr_ss_cmp; i++) {
> -		/* always clear status bit on restart if using single-shot */
> -		if (config->ss_ctrl[i] || config->ss_pe_cmp[i])
> -			config->ss_status[i] &= ~TRCSSCSRn_STATUS;
>   		etm4x_relaxed_write32(csa, config->ss_ctrl[i], TRCSSCCRn(i));
> -		etm4x_relaxed_write32(csa, config->ss_status[i], TRCSSCSRn(i));
> +		/* always clear status and pending bits on restart if using single-shot */
> +		etm4x_relaxed_write32(csa, 0x0, TRCSSCSRn(i));
>   		if (etm4x_sspcicrn_present(drvdata, i))
>   			etm4x_relaxed_write32(csa, config->ss_pe_cmp[i], TRCSSPCICRn(i));
>   	}
> @@ -1055,12 +1053,6 @@ static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
>   
>   	etm4_disable_trace_unit(drvdata);
>   
> -	/* read the status of the single shot comparators */
> -	for (i = 0; i < caps->nr_ss_cmp; i++) {
> -		config->ss_status[i] =
> -			etm4x_relaxed_read32(csa, TRCSSCSRn(i));
> -	}
> -
>   	/* read back the current counter values */
>   	for (i = 0; i < caps->nr_cntr; i++) {
>   		config->cntr_val[i] =
> @@ -1503,8 +1495,9 @@ static void etm4_init_arch_data(void *info)
>   	 */
>   	caps->nr_ss_cmp = FIELD_GET(TRCIDR4_NUMSSCC_MASK, etmidr4);
>   	for (i = 0; i < caps->nr_ss_cmp; i++) {
> -		drvdata->config.ss_status[i] =
> -			etm4x_relaxed_read32(csa, TRCSSCSRn(i));
> +		caps->ss_cmp[i] = etm4x_relaxed_read32(csa, TRCSSCSRn(i));
> +		caps->ss_cmp[i] &= (TRCSSCSRn_PC | TRCSSCSRn_DV |
> +				    TRCSSCSRn_DA | TRCSSCSRn_INST);

Just re-go through this patch and had a question here:

I’m not sure whether this new change should be documented in the ABI, 
given that the TRCSSCSRn_STATUS bit is masked. In my opinion, this 
change breaks the existing ABI description.

Description from the ABI document:

What:           /sys/bus/coresight/devices/etm<N>/sshot_status
Date:           December 2019
KernelVersion:  5.5
Contact:        Mathieu Poirier <mathieu.poirier@linaro.org>
Description:    (Read) Print the current value of the selected single
                 shot status register.

Thanks,
Jie

>   	}
>   	/* NUMCIDC, bits[27:24] number of Context ID comparators for tracing */
>   	caps->numcidc = FIELD_GET(TRCIDR4_NUMCIDC_MASK, etmidr4);
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> index 8bd28e71d4c9..5e26c2ec8f7b 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> @@ -1829,8 +1829,6 @@ static ssize_t sshot_ctrl_store(struct device *dev,
>   	raw_spin_lock(&drvdata->spinlock);
>   	idx = config->ss_idx;
>   	config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
> -	/* must clear bit 31 in related status register on programming */
> -	config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
>   	raw_spin_unlock(&drvdata->spinlock);
>   	return size;
>   }
> @@ -1841,10 +1839,11 @@ static ssize_t sshot_status_show(struct device *dev,
>   {
>   	unsigned long val;
>   	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
> +	const struct etmv4_caps *caps = &drvdata->caps;
>   	struct etmv4_config *config = &drvdata->config;
>   
>   	raw_spin_lock(&drvdata->spinlock);
> -	val = config->ss_status[config->ss_idx];
> +	val = caps->ss_cmp[config->ss_idx];
>   	raw_spin_unlock(&drvdata->spinlock);
>   	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>   }
> @@ -1879,8 +1878,6 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev,
>   	raw_spin_lock(&drvdata->spinlock);
>   	idx = config->ss_idx;
>   	config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);
> -	/* must clear bit 31 in related status register on programming */
> -	config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
>   	raw_spin_unlock(&drvdata->spinlock);
>   	return size;
>   }
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index 8168676f2945..db56c4414873 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -213,6 +213,7 @@
>   #define TRCACATRn_EXLEVEL_MASK			GENMASK(14, 8)
>   
>   #define TRCSSCSRn_STATUS			BIT(31)
> +#define TRCSSCSRn_PENDING			BIT(30)
>   #define TRCSSCCRn_SAC_ARC_RST_MASK		GENMASK(24, 0)
>   
>   #define TRCSSPCICRn_PC_MASK			GENMASK(7, 0)
> @@ -729,6 +730,9 @@ static inline u32 etm4_res_sel_pair(u8 res_sel_idx)
>   #define ETM_DEFAULT_ADDR_COMP		0
>   
>   #define TRCSSCSRn_PC			BIT(3)
> +#define TRCSSCSRn_DV			BIT(2)
> +#define TRCSSCSRn_DA			BIT(1)
> +#define TRCSSCSRn_INST			BIT(0)
>   
>   /* PowerDown Control Register bits */
>   #define TRCPDCR_PU			BIT(3)
> @@ -861,6 +865,7 @@ enum etm_impdef_type {
>    * @lpoverride:	If the implementation can support low-power state over.
>    * @skip_power_up: Indicates if an implementation can skip powering up
>    *		   the trace unit.
> + * @ss_cmp:	Indicates supported single-shot comparators.
>    */
>   struct etmv4_caps {
>   	u8	nr_pe;
> @@ -899,6 +904,7 @@ struct etmv4_caps {
>   	bool	atbtrig : 1;
>   	bool	lpoverride : 1;
>   	bool	skip_power_up : 1;
> +	u32	ss_cmp[ETM_MAX_SS_CMP];
>   };
>   
>   /**
> @@ -977,7 +983,6 @@ struct etmv4_config {
>   	u32				res_ctrl[ETM_MAX_RES_SEL]; /* TRCRSCTLRn */
>   	u8				ss_idx;
>   	u32				ss_ctrl[ETM_MAX_SS_CMP];
> -	u32				ss_status[ETM_MAX_SS_CMP];
>   	u32				ss_pe_cmp[ETM_MAX_SS_CMP];
>   	u8				addr_idx;
>   	u64				addr_val[ETM_MAX_SINGLE_ADDR_CMP];



^ permalink raw reply

* RE: [PATCH v4 3/9] media: chips-media: wave6: Add Wave6 VPU interface
From: Nas Chung @ 2026-04-16  5:25 UTC (permalink / raw)
  To: Nicolas Dufresne, mchehab@kernel.org, hverkuil@xs4all.nl,
	robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	shawnguo@kernel.org, s.hauer@pengutronix.de
  Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-imx@nxp.com,
	linux-arm-kernel@lists.infradead.org, jackson.lee, lafley.kim,
	marek.vasut@mailbox.org, Ming Qian
In-Reply-To: <7306c00b626f4030d92b908022b9a39669b07bb7.camel@ndufresne.ca>

Hi, Nicolas.

Sorry, I just realized that I never replied to your earlier email.

>-----Original Message-----
>From: Nicolas Dufresne <nicolas@ndufresne.ca>
>Sent: Thursday, December 11, 2025 4:54 AM
>To: Nas Chung <nas.chung@chipsnmedia.com>; mchehab@kernel.org;
>hverkuil@xs4all.nl; robh@kernel.org; krzk+dt@kernel.org;
>conor+dt@kernel.org; shawnguo@kernel.org; s.hauer@pengutronix.de
>Cc: linux-media@vger.kernel.org; devicetree@vger.kernel.org; linux-
>kernel@vger.kernel.org; linux-imx@nxp.com; linux-arm-
>kernel@lists.infradead.org; jackson.lee <jackson.lee@chipsnmedia.com>;
>lafley.kim <lafley.kim@chipsnmedia.com>; marek.vasut@mailbox.org; Ming Qian
><ming.qian@oss.nxp.com>
>Subject: Re: [PATCH v4 3/9] media: chips-media: wave6: Add Wave6 VPU
>interface
>
>Hi,
>
>Le mercredi 22 octobre 2025 à 16:47 +0900, Nas Chung a écrit :
>> Add an interface layer to manage hardware register configuration
>> and communication with the Chips&Media Wave6 video codec IP.
>>
>> The interface provides low-level helper functions used by the
>> Wave6 core driver to implement video encoding and decoding operations.
>> It handles command submission to the firmware via MMIO registers,
>> and waits for a response by polling the firmware busy flag.
>>
>> Signed-off-by: Nas Chung <nas.chung@chipsnmedia.com>
>> Tested-by: Ming Qian <ming.qian@oss.nxp.com>
>> Tested-by: Marek Vasut <marek.vasut@mailbox.org>
>> ---

[...]

>
>[...]
>
>stopping there for now. I feel like we did a big mistake in wave5 by
>allowing a
>heavy abstraction, its a lot harder to fix and it served no purpose since
>you
>went for a fresh driver for wave6. I think its proper to ask for a slimmer
>interface.
>
>The V4L2 API is the front-end, and where all the validation should take
>place.
>The HW interface should simply manage the HW in a readable and non-
>redundant
>way. In V4L2, strides and buffer size are part of the try/s/g_fmt API, so
>these
>should not be duplicated here and they should clearly use the common code.

I agree that the HW interface should be slimmer and should not duplicate
validation handled in the V4L2 layer.

>
>I know its painful to ear, but you will be remove 50% of the code, which
>long
>term will be a massive win on maintenance.

I am reworking the series to address your earlier feedback as well, and I will
include that in the next patch version.

Thanks again for your feedback.

Thanks.
Nas.

>
>regards,
>Nicolas


^ permalink raw reply

* Re: [PATCH] arm_pmu: acpi: fix reference leak on failed device registration
From: Greg Kroah-Hartman @ 2026-04-16  4:40 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Guangshuo Li, Will Deacon, Anshuman Khandual, linux-arm-kernel,
	linux-perf-users, linux-kernel, stable
In-Reply-To: <ad_WmuauLJ3xDKqh@J2N7QTR9R3>

On Wed, Apr 15, 2026 at 07:19:06PM +0100, Mark Rutland wrote:
> Hi,
> 
> Thanks for the patch, but from a quick skim, I don't think this is the right
> fix.
> 
> Greg, I think we might want to rework the core API here; question for
> you at the end.
> 
> On Thu, Apr 16, 2026 at 01:41:59AM +0800, Guangshuo Li wrote:
> > When platform_device_register() fails in arm_acpi_register_pmu_device(),
> > the embedded struct device in pdev has already been initialized by
> > device_initialize(), but the failure path only unregisters the GSI and
> > does not drop the device reference for the current platform device:
> > 
> >   arm_acpi_register_pmu_device()
> >     -> platform_device_register(pdev)
> >        -> device_initialize(&pdev->dev)
> >        -> setup_pdev_dma_masks(pdev)
> >        -> platform_device_add(pdev)
> > 
> > This leads to a reference leak when platform_device_register() fails.
> 
> AFAICT you're saying that the reference was taken *within*
> platform_device_register(), and then platform_device_register() itself
> has failed. I think it's surprising that platform_device_register()
> doesn't clean that up itself in the case of an error.
> 
> There are *tonnes* of calls to platform_device_register() throughout the
> kernel that don't even bother to check the return value, and many that
> just pass the return onto a caller that can't possibly know to call
> platform_device_put().
> 
> Code in the same file as platform_device_register() expects it to clean up
> after itself, e.g.
> 
> | int platform_add_devices(struct platform_device **devs, int num) 
> | {
> |         int i, ret = 0; 
> | 
> |         for (i = 0; i < num; i++) {
> |                 ret = platform_device_register(devs[i]);
> |                 if (ret) {
> |                         while (--i >= 0)
> |                                 platform_device_unregister(devs[i]);
> |                         break;
> |                 }    
> |         }    
> | 
> |         return ret; 
> | }
> 
> That's been there since the initial git commit, and back then,
> platform_device_register() didn't mention that callers needed to perform
> any cleanup.
> 
> I see a comment was added to platform_device_register() in commit:
> 
>   67e532a42cf4 ("driver core: platform: document registration-failure requirement")
> 
> ... and that copied the commend added for device_register() in commit:
> 
>   5739411acbaa ("Driver core: Clarify device cleanup.")
> 
> ... but the potential brokenness is so widespread, and the behaviour is
> so surprising, that I'd argue the real but is that device_register()
> doesn't clean up in case of error. I don't think it's worth changing
> this single instance given the prevalance and churn fixing all of that
> would involve.
> 
> I think it would be far better to fix the core driver API such that when
> those functions return an error, they've already cleaned up for
> themselves.
> 
> Greg, am I missing some functional reason why we can't rework
> device_register() and friends to handle cleanup themselves? I appreciate
> that'll involve churn for some callers, but AFAICT the majority of
> callers don't have the required cleanup.

Yes, we should fix the platform core code here, this should not be
required to do everywhere as obviously we all got it wrong.

Guangshuo, can you submit a patch to do that instead and ask for all of
your other patches to not be applied as well?

thanks,

greg k-h


^ permalink raw reply

* Re: [PATCH v5 07/12] coresight: etm4x: fix inconsistencies with sysfs configuration
From: Jie Gan @ 2026-04-16  4:35 UTC (permalink / raw)
  To: Yeoreum Yun, coresight, linux-arm-kernel, linux-kernel
  Cc: suzuki.poulose, mike.leach, james.clark, alexander.shishkin,
	leo.yan
In-Reply-To: <20260415165528.3369607-8-yeoreum.yun@arm.com>



On 4/16/2026 12:55 AM, Yeoreum Yun wrote:
> The current ETM4x configuration via sysfs can lead to
> several inconsistencies:
> 
>    - If the configuration is modified via sysfs while a perf session is
>      active, the running configuration may differ before a sched-out and
>      after a subsequent sched-in.
> 
>    - If a perf session and a sysfs session enable tracing concurrently,
>      the configuration from configfs may become corrupted.
> 
>    - There is a risk of corrupting drvdata->config if a perf session enables
>      tracing while cscfg_csdev_disable_active_config() is being handled in
>      etm4_disable_sysfs().
> 
> To resolve these issues, separate the configuration into:
> 
>    - active_config: the configuration applied to the current session
>    - config: the configuration set via sysfs
> 
> Additionally:
> 
>    - Apply the configuration from configfs after taking the appropriate mode.
> 
>    - Since active_config and related fields are accessed only by the local CPU
>      in etm4_enable/disable_sysfs_smp_call() (similar to perf enable/disable),
>      remove the lock/unlock from the sysfs enable/disable path and
>      startup/dying_cpu except when to access config fields.
> 
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> ---

<...>

> @@ -618,23 +624,45 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
>   static void etm4_enable_sysfs_smp_call(void *info)
>   {
>   	struct etm4_enable_arg *arg = info;
> +	struct etmv4_drvdata *drvdata;
>   	struct coresight_device *csdev;
>   
>   	if (WARN_ON(!arg))
>   		return;
>   
> -	csdev = arg->drvdata->csdev;
> +	drvdata = arg->drvdata;
> +	csdev = drvdata->csdev;
>   	if (!coresight_take_mode(csdev, CS_MODE_SYSFS)) {
>   		/* Someone is already using the tracer */
>   		arg->rc = -EBUSY;
>   		return;
>   	}
>   
> -	arg->rc = etm4_enable_hw(arg->drvdata);
> +	drvdata->active_config = arg->config;
>   
> -	/* The tracer didn't start */
> +	if (arg->cfg_hash) {
> +		arg->rc = cscfg_csdev_enable_active_config(csdev,
> +							   arg->cfg_hash,
> +							   arg->preset);
> +		if (arg->rc)
> +			goto err;
> +	}
> +
> +	drvdata->trcid = arg->trace_id;
> +
> +	/* Tracer will never be paused in sysfs mode */
> +	drvdata->paused = false;
> +
> +	arg->rc = etm4_enable_hw(drvdata);
>   	if (arg->rc)
> -		coresight_set_mode(csdev, CS_MODE_DISABLED);

needs disable the active config in error path:
cscfg_csdev_disable_active_config(drvdata->csdev);

Thanks,
Jie

> +		goto err;
> +
> +	drvdata->sticky_enable = true;
> +
> +	return;
> +err:
> +	/* The tracer didn't start */
> +	coresight_set_mode(csdev, CS_MODE_DISABLED);
>   }
>   
>   /*
> @@ -672,7 +700,7 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata,
>   	int ctridx;
>   	int rselector;
>   	const struct etmv4_caps *caps = &drvdata->caps;
> -	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_config *config = &drvdata->active_config;
>   
>   	/* No point in trying if we don't have at least one counter */
>   	if (!caps->nr_cntr)
> @@ -756,7 +784,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
>   	int ret = 0;
>   	struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>   	const struct etmv4_caps *caps = &drvdata->caps;
> -	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_config *config = &drvdata->active_config;
>   	struct perf_event_attr max_timestamp = {
>   		.ATTR_CFG_FLD_timestamp_CFG = U64_MAX,
>   	};
> @@ -918,40 +946,29 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa
>   
>   	/* enable any config activated by configfs */
>   	cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset);
> -	if (cfg_hash) {
> -		ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
> -		if (ret) {
> -			etm4_release_trace_id(drvdata);
> -			return ret;
> -		}
> -	}
> -
> -	raw_spin_lock(&drvdata->spinlock);
> -
> -	drvdata->trcid = path->trace_id;
> -
> -	/* Tracer will never be paused in sysfs mode */
> -	drvdata->paused = false;
>   
>   	/*
>   	 * Executing etm4_enable_hw on the cpu whose ETM is being enabled
>   	 * ensures that register writes occur when cpu is powered.
>   	 */
>   	arg.drvdata = drvdata;
> +	arg.cfg_hash = cfg_hash;
> +	arg.preset = preset;
> +	arg.trace_id = path->trace_id;
> +
> +	raw_spin_lock(&drvdata->spinlock);
> +	arg.config = drvdata->config;
> +	raw_spin_unlock(&drvdata->spinlock);
> +
>   	ret = smp_call_function_single(drvdata->cpu,
>   				       etm4_enable_sysfs_smp_call, &arg, 1);
>   	if (!ret)
>   		ret = arg.rc;
>   	if (!ret)
> -		drvdata->sticky_enable = true;
> -
> -	if (ret)
> +		dev_dbg(&csdev->dev, "ETM tracing enabled\n");
> +	else
>   		etm4_release_trace_id(drvdata);
>   
> -	raw_spin_unlock(&drvdata->spinlock);
> -
> -	if (!ret)
> -		dev_dbg(&csdev->dev, "ETM tracing enabled\n");
>   	return ret;
>   }
>   
> @@ -1038,7 +1055,7 @@ static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
>   {
>   	u32 control;
>   	const struct etmv4_caps *caps = &drvdata->caps;
> -	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_config *config = &drvdata->active_config;
>   	struct coresight_device *csdev = drvdata->csdev;
>   	struct csdev_access *csa = &csdev->access;
>   	int i;
> @@ -1074,6 +1091,8 @@ static void etm4_disable_sysfs_smp_call(void *info)
>   
>   	etm4_disable_hw(drvdata);
>   
> +	cscfg_csdev_disable_active_config(drvdata->csdev);
> +
>   	coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED);
>   }
>   
> @@ -1124,7 +1143,6 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
>   	 * DYING hotplug callback is serviced by the ETM driver.
>   	 */
>   	cpus_read_lock();
> -	raw_spin_lock(&drvdata->spinlock);
>   
>   	/*
>   	 * Executing etm4_disable_hw on the cpu whose ETM is being disabled
> @@ -1133,10 +1151,6 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
>   	smp_call_function_single(drvdata->cpu, etm4_disable_sysfs_smp_call,
>   				 drvdata, 1);
>   
> -	raw_spin_unlock(&drvdata->spinlock);
> -
> -	cscfg_csdev_disable_active_config(csdev);
> -
>   	cpus_read_unlock();
>   
>   	/*
> @@ -1379,6 +1393,7 @@ static void etm4_init_arch_data(void *info)
>   	struct etm4_init_arg *init_arg = info;
>   	struct etmv4_drvdata *drvdata;
>   	struct etmv4_caps *caps;
> +	struct etmv4_config *config;
>   	struct csdev_access *csa;
>   	struct device *dev = init_arg->dev;
>   	int i;
> @@ -1386,6 +1401,7 @@ static void etm4_init_arch_data(void *info)
>   	drvdata = dev_get_drvdata(init_arg->dev);
>   	caps = &drvdata->caps;
>   	csa = init_arg->csa;
> +	config = &drvdata->active_config;
>   
>   	/*
>   	 * If we are unable to detect the access mechanism,
> @@ -1446,7 +1462,7 @@ static void etm4_init_arch_data(void *info)
>   
>   	/* EXLEVEL_S, bits[19:16] Secure state instruction tracing */
>   	caps->s_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_S_MASK, etmidr3);
> -	drvdata->config.s_ex_level = caps->s_ex_level;
> +	config->s_ex_level = caps->s_ex_level;
>   	/* EXLEVEL_NS, bits[23:20] Non-secure state instruction tracing */
>   	caps->ns_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_NS_MASK, etmidr3);
>   	/*
> @@ -1692,7 +1708,7 @@ static void etm4_set_default(struct etmv4_config *config)
>   static int etm4_get_next_comparator(struct etmv4_drvdata *drvdata, u32 type)
>   {
>   	int nr_comparator, index = 0;
> -	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_config *config = &drvdata->active_config;
>   
>   	/*
>   	 * nr_addr_cmp holds the number of comparator _pair_, so time 2
> @@ -1733,7 +1749,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
>   {
>   	int i, comparator, ret = 0;
>   	u64 address;
> -	struct etmv4_config *config = &drvdata->config;
> +	struct etmv4_config *config = &drvdata->active_config;
>   	struct etm_filters *filters = event->hw.addr_filters;
>   
>   	if (!filters)
> @@ -1851,13 +1867,11 @@ static int etm4_starting_cpu(unsigned int cpu)
>   	if (!etmdrvdata[cpu])
>   		return 0;
>   
> -	raw_spin_lock(&etmdrvdata[cpu]->spinlock);
>   	if (!etmdrvdata[cpu]->os_unlock)
>   		etm4_os_unlock(etmdrvdata[cpu]);
>   
>   	if (coresight_get_mode(etmdrvdata[cpu]->csdev))
>   		etm4_enable_hw(etmdrvdata[cpu]);
> -	raw_spin_unlock(&etmdrvdata[cpu]->spinlock);
>   	return 0;
>   }
>   
> @@ -1866,10 +1880,8 @@ static int etm4_dying_cpu(unsigned int cpu)
>   	if (!etmdrvdata[cpu])
>   		return 0;
>   
> -	raw_spin_lock(&etmdrvdata[cpu]->spinlock);
>   	if (coresight_get_mode(etmdrvdata[cpu]->csdev))
>   		etm4_disable_hw(etmdrvdata[cpu]);
> -	raw_spin_unlock(&etmdrvdata[cpu]->spinlock);
>   	return 0;
>   }
>   
> @@ -2255,7 +2267,8 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
>   	if (!desc.name)
>   		return -ENOMEM;
>   
> -	etm4_set_default(&drvdata->config);
> +	etm4_set_default(&drvdata->active_config);
> +	drvdata->config = drvdata->active_config;
>   
>   	pdata = coresight_get_platform_data(dev);
>   	if (IS_ERR(pdata))
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index cbd8890d166a..9b50aaa368cf 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -1069,6 +1069,7 @@ struct etmv4_save_state {
>    *		allows tracing at all ELs. We don't want to compute this
>    *		at runtime, due to the additional setting of TRFCR_CX when
>    *		in EL2. Otherwise, 0.
> + * @active_config:	structure holding current applied configuration parameters.
>    * @config:	structure holding configuration parameters.
>    * @save_state:	State to be preserved across power loss
>    * @paused:	Indicates if the trace unit is paused.
> @@ -1089,6 +1090,7 @@ struct etmv4_drvdata {
>   	bool				os_unlock : 1;
>   	bool				paused : 1;
>   	u64				trfcr;
> +	struct etmv4_config		active_config;
>   	struct etmv4_config		config;
>   	struct etmv4_save_state		*save_state;
>   	DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX);



^ permalink raw reply

* Re: [PATCH v3 1/6] soc: mediatek: mtk-devapc: refine devapc interrupt handler
From: CK Hu (胡俊光) @ 2026-04-16  3:45 UTC (permalink / raw)
  To: robh@kernel.org, Xiaoshun Xu (徐晓顺),
	krzk+dt@kernel.org, conor+dt@kernel.org, matthias.bgg@gmail.com,
	AngeloGioacchino Del Regno
  Cc: linux-arm-kernel@lists.infradead.org,
	linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Sirius Wang (王皓昱),
	Project_Global_Chrome_Upstream_Group,
	Vince-WL Liu (劉文龍)
In-Reply-To: <20260416031231.2932493-2-xiaoshun.xu@mediatek.com>

On Thu, 2026-04-16 at 11:12 +0800, Xiaoshun Xu wrote:
> Because the violation IRQ uses a while loop, it might cause the
> system to remain in the interrupt handler indefinitely. We are
> currently optimizing this part of the process to handle only 20
> violations for debug violation issues, and then exit the loop
> 
> Signed-off-by: Xiaoshun Xu <xiaoshun.xu@mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-devapc.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
> index f54c966138b5..c9e1401315ad 100644
> --- a/drivers/soc/mediatek/mtk-devapc.c
> +++ b/drivers/soc/mediatek/mtk-devapc.c
> @@ -12,6 +12,7 @@
>  #include <linux/of_irq.h>
>  #include <linux/of_address.h>
>  
> +#define MAX_VIO_NUM 20
>  #define VIO_MOD_TO_REG_IND(m)	((m) / 32)
>  #define VIO_MOD_TO_REG_OFF(m)	((m) % 32)
>  
> @@ -188,13 +189,18 @@ static void devapc_extract_vio_dbg(struct mtk_devapc_context *ctx)
>   */
>  static irqreturn_t devapc_violation_irq(int irq_number, void *data)
>  {
> +	u32 vio_num = 0;
>  	struct mtk_devapc_context *ctx = data;
>  
> -	while (devapc_sync_vio_dbg(ctx))
> +	mask_module_irq(ctx, true);

mask irq is not related to this patch. This patch care about the infinite loop.
So separate mask irq part to an independent patch and describe why do this.

Regards,
CK

> +
> +	for (vio_num = 0; (vio_num < MAX_VIO_NUM) && (devapc_sync_vio_dbg(ctx)); ++vio_num)
>  		devapc_extract_vio_dbg(ctx);
>  
>  	clear_vio_status(ctx);
>  
> +	mask_module_irq(ctx, false);
> +
>  	return IRQ_HANDLED;
>  }
>  


^ permalink raw reply

* Re: [PATCH v13 3/3] of: Respect #{iommu,msi}-cells in maps
From: Vijayanand Jitta @ 2026-04-16  3:26 UTC (permalink / raw)
  To: Nipun Gupta, Nikhil Agarwal, Joerg Roedel, Will Deacon,
	Robin Murphy, Marc Zyngier, Lorenzo Pieralisi, Thomas Gleixner,
	Saravana Kannan, Richard Zhu, Lucas Stach,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Bjorn Helgaas,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Dmitry Baryshkov, Konrad Dybcio, Bjorn Andersson, Rob Herring,
	Conor Dooley, Krzysztof Kozlowski, Prakash Gupta, Vikash Garodia
  Cc: linux-kernel, iommu, linux-arm-kernel, devicetree, linux-pci, imx,
	xen-devel, linux-arm-msm, Charan Teja Kalla
In-Reply-To: <20260408-parse_iommu_cells-v13-3-fa921e92661b@oss.qualcomm.com>



On 4/8/2026 3:33 PM, Vijayanand Jitta wrote:
> From: Robin Murphy <robin.murphy@arm.com>
> 
> So far our parsing of {iommu,msi}-map properties has always blindly
> assumed that the output specifiers will always have exactly 1 cell.
> This typically does happen to be the case, but is not actually enforced
> (and the PCI msi-map binding even explicitly states support for 0 or 1
> cells) - as a result we've now ended up with dodgy DTs out in the field
> which depend on this behaviour to map a 1-cell specifier for a 2-cell
> provider, despite that being bogus per the bindings themselves.
> 
> Since there is some potential use in being able to map at least single
> input IDs to multi-cell output specifiers (and properly support 0-cell
> outputs as well), add support for properly parsing and using the target
> nodes' #cells values, albeit with the unfortunate complication of still
> having to work around expectations of the old behaviour too.
> 
> Since there are multi-cell output specifiers, the callers of of_map_id()
> may need to get the exact cell output value for further processing.
> Update of_map_id() to set args_count in the output to reflect the actual
> number of output specifier cells.
> 
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> Signed-off-by: Charan Teja Kalla <charan.kalla@oss.qualcomm.com>
> Signed-off-by: Vijayanand Jitta <vijayanand.jitta@oss.qualcomm.com>
> ---
>  drivers/of/base.c  | 157 +++++++++++++++++++++++++++++++++++++++++------------
>  include/linux/of.h |   6 +-
>  2 files changed, 125 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index b3d002015192..2554e4f1a181 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -2096,18 +2096,48 @@ int of_find_last_cache_level(unsigned int cpu)
>  	return cache_level;
>  }
>  
> +/*
> + * Some DTs have an iommu-map targeting a 2-cell IOMMU node while
> + * specifying only 1 cell. Fortunately they all consist of value '1'
> + * as the 2nd cell entry with the same target, so check for that pattern.
> + *
> + * Example:
> + *	IOMMU node:
> + *		#iommu-cells = <2>;
> + *
> + *	Device node:
> + *		iommu-map = <0x0000 &smmu 0x0000 0x1>,
> + *			    <0x0100 &smmu 0x0100 0x1>;
> + */
> +static bool of_check_bad_map(const __be32 *map, int len)
> +{
> +	__be32 phandle = map[1];
> +
> +	if (len % 4)
> +		return false;
> +	for (int i = 0; i < len; i += 4) {
> +		if (map[i + 1] != phandle || map[i + 3] != cpu_to_be32(1))
> +			return false;
> +	}
> +	return true;
> +}
> +
>  /**
>   * of_map_id - Translate an ID through a downstream mapping.
>   * @np: root complex device node.
>   * @id: device ID to map.
>   * @map_name: property name of the map to use.
> + * @cells_name: property name of target specifier cells.
>   * @map_mask_name: optional property name of the mask to use.
>   * @filter_np: optional device node to filter matches by, or NULL to match any.
>   *	If non-NULL, only map entries targeting this node will be matched.
>   * @arg: pointer to a &struct of_phandle_args for the result. On success,
> - *	@arg->args[0] will contain the translated ID. If a map entry was
> - *	matched, @arg->np will be set to the target node with a reference
> - *	held that the caller must release with of_node_put().
> + *	@arg->args_count will be set to the number of output specifier cells
> + *	as defined by @cells_name in the target node, and
> + *	@arg->args[0..args_count-1] will contain the translated output
> + *	specifier values. If a map entry was matched, @arg->np will be set
> + *	to the target node with a reference held that the caller must release
> + *	with of_node_put().
>   *
>   * Given a device ID, look up the appropriate implementation-defined
>   * platform ID and/or the target device which receives transactions on that
> @@ -2116,17 +2146,19 @@ int of_find_last_cache_level(unsigned int cpu)
>   * Return: 0 on success or a standard error code on failure.
>   */
>  int of_map_id(const struct device_node *np, u32 id,
> -	       const char *map_name, const char *map_mask_name,
> +	       const char *map_name, const char *cells_name,
> +	       const char *map_mask_name,
>  	       const struct device_node *filter_np, struct of_phandle_args *arg)
>  {
>  	u32 map_mask, masked_id;
> -	int map_len;
> +	int map_bytes, map_len, offset = 0;
> +	bool bad_map = false;
>  	const __be32 *map = NULL;
>  
>  	if (!np || !map_name || !arg)
>  		return -EINVAL;
>  
> -	map = of_get_property(np, map_name, &map_len);
> +	map = of_get_property(np, map_name, &map_bytes);
>  	if (!map) {
>  		if (filter_np)
>  			return -ENODEV;
> @@ -2136,11 +2168,9 @@ int of_map_id(const struct device_node *np, u32 id,
>  		return 0;
>  	}
>  
> -	if (!map_len || map_len % (4 * sizeof(*map))) {
> -		pr_err("%pOF: Error: Bad %s length: %d\n", np,
> -			map_name, map_len);
> -		return -EINVAL;
> -	}
> +	if (map_bytes % sizeof(*map))
> +		goto err_map_len;
> +	map_len = map_bytes / sizeof(*map);
>  
>  	/* The default is to select all bits. */
>  	map_mask = 0xffffffff;
> @@ -2153,39 +2183,84 @@ int of_map_id(const struct device_node *np, u32 id,
>  		of_property_read_u32(np, map_mask_name, &map_mask);
>  
>  	masked_id = map_mask & id;
> -	for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
> +
> +	while (offset < map_len) {
>  		struct device_node *phandle_node;
> -		u32 id_base = be32_to_cpup(map + 0);
> -		u32 phandle = be32_to_cpup(map + 1);
> -		u32 out_base = be32_to_cpup(map + 2);
> -		u32 id_len = be32_to_cpup(map + 3);
> +		u32 id_base, phandle, id_len, id_off, cells = 0;
> +		const __be32 *out_base;
> +
> +		if (map_len - offset < 2)
> +			goto err_map_len;
> +
> +		id_base = be32_to_cpup(map + offset);
>  
>  		if (id_base & ~map_mask) {
> -			pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores id-base (0x%x)\n",
> -				np, map_name, map_name,
> -				map_mask, id_base);
> +			pr_err("%pOF: Invalid %s translation - %s (0x%x) ignores id-base (0x%x)\n",
> +			       np, map_name, map_mask_name, map_mask, id_base);
>  			return -EFAULT;
>  		}
>  
> -		if (masked_id < id_base || masked_id >= id_base + id_len)
> -			continue;
> -
> +		phandle = be32_to_cpup(map + offset + 1);
>  		phandle_node = of_find_node_by_phandle(phandle);
>  		if (!phandle_node)
>  			return -ENODEV;
>  
> +		if (bad_map) {
> +			cells = 1;
> +		} else if (of_property_read_u32(phandle_node, cells_name, &cells)) {
> +			pr_err("%pOF: missing %s property\n", phandle_node, cells_name);
> +			of_node_put(phandle_node);
> +			return -EINVAL;
> +		}
> +
> +		if (map_len - offset < 3 + cells) {
> +			of_node_put(phandle_node);
> +			goto err_map_len;
> +		}
> +
> +		if (offset == 0 && cells == 2) {
> +			bad_map = of_check_bad_map(map, map_len);
> +			if (bad_map) {
> +				pr_warn_once("%pOF: %s mismatches target %s, assuming extra cell of 0\n",
> +					     np, map_name, cells_name);
> +				cells = 1;
> +			}
> +		}
> +
> +		out_base = map + offset + 2;
> +		offset += 3 + cells;
> +
> +		id_len = be32_to_cpup(map + offset - 1);
> +		if (id_len > 1 && cells > 1) {
> +			/*
> +			 * With 1 output cell we reasonably assume its value
> +			 * has a linear relationship to the input; with more,
> +			 * we'd need help from the provider to know what to do.
> +			 */
> +			pr_err("%pOF: Unsupported %s - cannot handle %d-ID range with %d-cell output specifier\n",
> +			       np, map_name, id_len, cells);
> +			of_node_put(phandle_node);
> +			return -EINVAL;
> +		}
> +		id_off = masked_id - id_base;
> +		if (masked_id < id_base || id_off >= id_len) {
> +			of_node_put(phandle_node);
> +			continue;
> +		}
> +
>  		if (filter_np && filter_np != phandle_node) {
>  			of_node_put(phandle_node);
>  			continue;
>  		}
>  
>  		arg->np = phandle_node;
> -		arg->args[0] = masked_id - id_base + out_base;
> -		arg->args_count = 1;
> +		for (int i = 0; i < cells; i++)
> +			arg->args[i] = id_off + be32_to_cpu(out_base[i]);
> +		arg->args_count = cells;
>  
>  		pr_debug("%pOF: %s, using mask %08x, id-base: %08x, out-base: %08x, length: %08x, id: %08x -> %08x\n",
> -			np, map_name, map_mask, id_base, out_base,
> -			id_len, id, masked_id - id_base + out_base);
> +			np, map_name, map_mask, id_base, be32_to_cpup(out_base),
> +			id_len, id, id_off + be32_to_cpup(out_base));
>  		return 0;
>  	}
>  
> @@ -2196,6 +2271,10 @@ int of_map_id(const struct device_node *np, u32 id,
>  	arg->args[0] = id;
>  	arg->args_count = 1;
>  	return 0;
> +
> +err_map_len:
> +	pr_err("%pOF: Error: Bad %s length: %d\n", np, map_name, map_bytes);
> +	return -EINVAL;
>  }
>  EXPORT_SYMBOL_GPL(of_map_id);
>  
> @@ -2205,18 +2284,21 @@ EXPORT_SYMBOL_GPL(of_map_id);
>   * @id: Requester ID of the device (e.g. PCI RID/BDF or a platform
>   *      stream/device ID) used as the lookup key in the iommu-map table.
>   * @arg: pointer to a &struct of_phandle_args for the result. On success,
> - *	@arg->args[0] contains the translated ID. If a map entry was matched,
> - *	@arg->np holds a reference to the target node that the caller must
> - *	release with of_node_put().
> + *	@arg->args_count will be set to the number of output specifier cells
> + *	and @arg->args[0..args_count-1] will contain the translated output
> + *	specifier values. If a map entry was matched, @arg->np holds a
> + *	reference to the target node that the caller must release with
> + *	of_node_put().
>   *
> - * Convenience wrapper around of_map_id() using "iommu-map" and "iommu-map-mask".
> + * Convenience wrapper around of_map_id() using "iommu-map", "#iommu-cells",
> + * and "iommu-map-mask".
>   *
>   * Return: 0 on success or a standard error code on failure.
>   */
>  int of_map_iommu_id(const struct device_node *np, u32 id,
>  		    struct of_phandle_args *arg)
>  {
> -	return of_map_id(np, id, "iommu-map", "iommu-map-mask", NULL, arg);
> +	return of_map_id(np, id, "iommu-map", "#iommu-cells", "iommu-map-mask", NULL, arg);
>  }
>  EXPORT_SYMBOL_GPL(of_map_iommu_id);
>  
> @@ -2229,17 +2311,20 @@ EXPORT_SYMBOL_GPL(of_map_iommu_id);
>   *	to match any. If non-NULL, only map entries targeting this node will
>   *	be matched.
>   * @arg: pointer to a &struct of_phandle_args for the result. On success,
> - *	@arg->args[0] contains the translated ID. If a map entry was matched,
> - *	@arg->np holds a reference to the target node that the caller must
> - *	release with of_node_put().
> + *	@arg->args_count will be set to the number of output specifier cells
> + *	and @arg->args[0..args_count-1] will contain the translated output
> + *	specifier values. If a map entry was matched, @arg->np holds a
> + *	reference to the target node that the caller must release with
> + *	of_node_put().
>   *
> - * Convenience wrapper around of_map_id() using "msi-map" and "msi-map-mask".
> + * Convenience wrapper around of_map_id() using "msi-map", "#msi-cells",
> + * and "msi-map-mask".
>   *
>   * Return: 0 on success or a standard error code on failure.
>   */
>  int of_map_msi_id(const struct device_node *np, u32 id,
>  		  const struct device_node *filter_np, struct of_phandle_args *arg)
>  {
> -	return of_map_id(np, id, "msi-map", "msi-map-mask", filter_np, arg);
> +	return of_map_id(np, id, "msi-map", "#msi-cells", "msi-map-mask", filter_np, arg);
>  }
>  EXPORT_SYMBOL_GPL(of_map_msi_id);
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 8548cd9eb4f1..51ac8539f2c3 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -462,7 +462,8 @@ const char *of_prop_next_string(const struct property *prop, const char *cur);
>  bool of_console_check(const struct device_node *dn, char *name, int index);
>  
>  int of_map_id(const struct device_node *np, u32 id,
> -	       const char *map_name, const char *map_mask_name,
> +	       const char *map_name, const char *cells_name,
> +	       const char *map_mask_name,
>  	       const struct device_node *filter_np, struct of_phandle_args *arg);
>  
>  int of_map_iommu_id(const struct device_node *np, u32 id,
> @@ -934,7 +935,8 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag
>  }
>  
>  static inline int of_map_id(const struct device_node *np, u32 id,
> -			     const char *map_name, const char *map_mask_name,
> +			     const char *map_name, const char *cells_name,
> +			     const char *map_mask_name,
>  			     const struct device_node *filter_np,
>  			     struct of_phandle_args *arg)
>  {
> 

Gentle ping.

Thanks,
Vijay


^ permalink raw reply

* [PATCH v3 5/6] soc: mediatek: mtk-devapc: Add support for MT8196 DEVAPC
From: Xiaoshun Xu @ 2026-04-16  3:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Xiaoshun Xu
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	Sirius Wang, Vince-wl Liu, Project_Global_Chrome_Upstream_Group
In-Reply-To: <20260416031231.2932493-1-xiaoshun.xu@mediatek.com>

Add support for MT8196 DEVAPC, MT8196 DEVAPC debug registers are
version 3 and add compatible for MT8196

Signed-off-by: Xiaoshun Xu <xiaoshun.xu@mediatek.com>
---
 drivers/soc/mediatek/mtk-devapc.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
index 824b49613c5a..0f828028bdb4 100644
--- a/drivers/soc/mediatek/mtk-devapc.c
+++ b/drivers/soc/mediatek/mtk-devapc.c
@@ -324,6 +324,11 @@ static const struct mtk_devapc_data devapc_mt8189 = {
 	.regs_ofs = &devapc_regs_ofs_ver3,
 };
 
+static const struct mtk_devapc_data devapc_mt8196 = {
+	.version = 3,
+	.regs_ofs = &devapc_regs_ofs_ver3,
+};
+
 static const struct of_device_id mtk_devapc_dt_match[] = {
 	{
 		.compatible = "mediatek,mt6779-devapc",
@@ -334,6 +339,9 @@ static const struct of_device_id mtk_devapc_dt_match[] = {
 	}, {
 		.compatible = "mediatek,mt8189-devapc",
 		.data = &devapc_mt8189,
+	}, {
+		.compatible = "mediatek,mt8196-devapc",
+		.data = &devapc_mt8196,
 	}, {
 	},
 };
-- 
2.45.2



^ permalink raw reply related

* [PATCH v3 6/6] dt-bindings: soc: mediatek: devapc: Add bindings for MT8196
From: Xiaoshun Xu @ 2026-04-16  3:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Xiaoshun Xu
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	Sirius Wang, Vince-wl Liu, Project_Global_Chrome_Upstream_Group
In-Reply-To: <20260416031231.2932493-1-xiaoshun.xu@mediatek.com>

Extend the devapc device tree bindings to support the MediaTek MT8196
SoC. This includes:

- Adding "mediatek,mt8196-devapc" to the list of compatible strings.

These changes enable proper configuration and integration of devapc on
MT8196 platforms, ensuring accurate device matching and resource
allocation in the device tree.

Signed-off-by: Xiaoshun Xu <xiaoshun.xu@mediatek.com>
---
 Documentation/devicetree/bindings/soc/mediatek/devapc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml b/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml
index 06a096440331..5eb260bf3dde 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml
@@ -22,6 +22,7 @@ properties:
       - mediatek,mt6779-devapc
       - mediatek,mt8186-devapc
       - mediatek,mt8189-devapc
+      - mediatek,mt8196-devapc
 
   reg:
     description: The base address of devapc register bank
-- 
2.45.2



^ permalink raw reply related

* [PATCH v3 4/6] dt-bindings: soc: mediatek: devapc: Add bindings for MT8189
From: Xiaoshun Xu @ 2026-04-16  3:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Xiaoshun Xu
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	Sirius Wang, Vince-wl Liu, Project_Global_Chrome_Upstream_Group
In-Reply-To: <20260416031231.2932493-1-xiaoshun.xu@mediatek.com>

Extend the devapc device tree bindings to support the MediaTek MT8189
SoC. This includes:

- Adding "mediatek,mt8189-devapc" to the list of compatible strings.
- Introducing the "vio-idx-num" property to specify the number of bus
  slaves managed by devapc.

These changes enable proper configuration and integration of devapc on
MT8189 platforms, ensuring accurate device matching and resource
allocation in the device tree.

Signed-off-by: Xiaoshun Xu <xiaoshun.xu@mediatek.com>
---
 .../devicetree/bindings/soc/mediatek/devapc.yaml       | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml b/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml
index 99e2caafeadf..06a096440331 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml
@@ -14,13 +14,14 @@ description: |
   analysis and countermeasures.
 
 maintainers:
-  - Neal Liu <neal.liu@mediatek.com>
+  - Xiaoshun Xu <xiaoshun.xu@mediatek.com>
 
 properties:
   compatible:
     enum:
       - mediatek,mt6779-devapc
       - mediatek,mt8186-devapc
+      - mediatek,mt8189-devapc
 
   reg:
     description: The base address of devapc register bank
@@ -30,6 +31,10 @@ properties:
     description: A single interrupt specifier
     maxItems: 1
 
+  vio-idx-num:
+    description: Describe the number of bus slaves controlled by devapc
+    $ref: /schemas/types.yaml#/definitions/uint32
+
   clocks:
     description: Contains module clock source and clock names
     maxItems: 1
@@ -42,8 +47,6 @@ required:
   - compatible
   - reg
   - interrupts
-  - clocks
-  - clock-names
 
 additionalProperties: false
 
@@ -55,6 +58,7 @@ examples:
     devapc: devapc@10207000 {
       compatible = "mediatek,mt6779-devapc";
       reg = <0x10207000 0x1000>;
+      vio-idx-num = <132>;
       interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_LOW>;
       clocks = <&infracfg_ao CLK_INFRA_DEVICE_APC>;
       clock-names = "devapc-infra-clock";
-- 
2.45.2



^ permalink raw reply related

* [PATCH v3 3/6] soc: mediatek: mtk-devapc: Add support for MT8189 DEVAPC
From: Xiaoshun Xu @ 2026-04-16  3:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Xiaoshun Xu
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	Sirius Wang, Vince-wl Liu, Project_Global_Chrome_Upstream_Group
In-Reply-To: <20260416031231.2932493-1-xiaoshun.xu@mediatek.com>

Add support for MT8189 DEVAPC, DEVAPC debug registers have new version,
so refine the structure of devapc_regs_ofs_xxxx to devapc_regs_ofs_verX,
and rename the infra_base to base in mtk_devapc_context because devapc
not only access the infra_base to dump debug information when violation
happens

Signed-off-by: Xiaoshun Xu <xiaoshun.xu@mediatek.com>
---
 drivers/soc/mediatek/mtk-devapc.c | 171 +++++++++++++++++++++++-------
 1 file changed, 134 insertions(+), 37 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
index f54e310791e5..824b49613c5a 100644
--- a/drivers/soc/mediatek/mtk-devapc.c
+++ b/drivers/soc/mediatek/mtk-devapc.c
@@ -27,9 +27,19 @@ struct mtk_devapc_vio_dbgs {
 			u32 addr_h:4;
 			u32 resv:4;
 		} dbg0_bits;
+
+		struct {
+			u32 dmnid:6;
+			u32 vio_w:1;
+			u32 vio_r:1;
+			u32 addr_h:4;
+			u32 resv:20;
+		} dbg0_bits_ver2;
 	};
 
 	u32 vio_dbg1;
+	u32 vio_dbg2;
+	u32 vio_dbg3;
 };
 
 struct mtk_devapc_regs_ofs {
@@ -38,6 +48,8 @@ struct mtk_devapc_regs_ofs {
 	u32 vio_sta_offset;
 	u32 vio_dbg0_offset;
 	u32 vio_dbg1_offset;
+	u32 vio_dbg2_offset;
+	u32 vio_dbg3_offset;
 	u32 apc_con_offset;
 	u32 vio_shift_sta_offset;
 	u32 vio_shift_sel_offset;
@@ -45,16 +57,20 @@ struct mtk_devapc_regs_ofs {
 };
 
 struct mtk_devapc_data {
-	/* numbers of violation index */
-	u32 vio_idx_num;
+	u32 version;
+	/* Default numbers of violation index */
+	u32 default_vio_idx_num;
 	const struct mtk_devapc_regs_ofs *regs_ofs;
 };
 
 struct mtk_devapc_context {
 	struct device *dev;
-	void __iomem *infra_base;
+	void __iomem *base;
 	struct clk *infra_clk;
 	const struct mtk_devapc_data *data;
+
+	/* numbers of violation index */
+	u32 vio_idx_num;
 };
 
 static void clear_vio_status(struct mtk_devapc_context *ctx)
@@ -62,12 +78,12 @@ static void clear_vio_status(struct mtk_devapc_context *ctx)
 	void __iomem *reg;
 	int i;
 
-	reg = ctx->infra_base + ctx->data->regs_ofs->vio_sta_offset;
+	reg = ctx->base + ctx->data->regs_ofs->vio_sta_offset;
 
-	for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1; i++)
+	for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->vio_idx_num - 1); i++)
 		writel(GENMASK(31, 0), reg + 4 * i);
 
-	writel(GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1, 0),
+	writel(GENMASK(VIO_MOD_TO_REG_OFF(ctx->vio_idx_num - 1), 0),
 	       reg + 4 * i);
 }
 
@@ -77,22 +93,22 @@ static void mask_module_irq(struct mtk_devapc_context *ctx, bool mask)
 	u32 val;
 	int i;
 
-	reg = ctx->infra_base + ctx->data->regs_ofs->vio_mask_offset;
+	reg = ctx->base + ctx->data->regs_ofs->vio_mask_offset;
 
 	if (mask)
 		val = GENMASK(31, 0);
 	else
 		val = 0;
 
-	for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1; i++)
+	for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->vio_idx_num - 1); i++)
 		writel(val, reg + 4 * i);
 
 	val = readl(reg + 4 * i);
 	if (mask)
-		val |= GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1,
+		val |= GENMASK(VIO_MOD_TO_REG_OFF(ctx->vio_idx_num - 1),
 			       0);
 	else
-		val &= ~GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1,
+		val &= ~GENMASK(VIO_MOD_TO_REG_OFF(ctx->vio_idx_num - 1),
 				0);
 
 	writel(val, reg + 4 * i);
@@ -119,11 +135,11 @@ static int devapc_sync_vio_dbg(struct mtk_devapc_context *ctx)
 	int ret;
 	u32 val;
 
-	pd_vio_shift_sta_reg = ctx->infra_base +
+	pd_vio_shift_sta_reg = ctx->base +
 			       ctx->data->regs_ofs->vio_shift_sta_offset;
-	pd_vio_shift_sel_reg = ctx->infra_base +
+	pd_vio_shift_sel_reg = ctx->base +
 			       ctx->data->regs_ofs->vio_shift_sel_offset;
-	pd_vio_shift_con_reg = ctx->infra_base +
+	pd_vio_shift_con_reg = ctx->base +
 			       ctx->data->regs_ofs->vio_shift_con_offset;
 
 	/* Find the minimum shift group which has violation */
@@ -134,7 +150,7 @@ static int devapc_sync_vio_dbg(struct mtk_devapc_context *ctx)
 	min_shift_group = __ffs(val);
 
 	/* Assign the group to sync */
-	writel(0x1 << min_shift_group, pd_vio_shift_sel_reg);
+	writel(BIT(min_shift_group), pd_vio_shift_sel_reg);
 
 	/* Start syncing */
 	writel(0x1, pd_vio_shift_con_reg);
@@ -150,7 +166,7 @@ static int devapc_sync_vio_dbg(struct mtk_devapc_context *ctx)
 	writel(0x0, pd_vio_shift_con_reg);
 
 	/* Write clear */
-	writel(0x1 << min_shift_group, pd_vio_shift_sta_reg);
+	writel(BIT(min_shift_group), pd_vio_shift_sta_reg);
 
 	return true;
 }
@@ -164,22 +180,52 @@ static void devapc_extract_vio_dbg(struct mtk_devapc_context *ctx)
 	struct mtk_devapc_vio_dbgs vio_dbgs;
 	void __iomem *vio_dbg0_reg;
 	void __iomem *vio_dbg1_reg;
+	void __iomem *vio_dbg2_reg;
+	void __iomem *vio_dbg3_reg;
+	u32 vio_addr_l, vio_addr_h, bus_id, domain_id;
+	u32 vio_w, vio_r;
+	u64 vio_addr;
 
-	vio_dbg0_reg = ctx->infra_base + ctx->data->regs_ofs->vio_dbg0_offset;
-	vio_dbg1_reg = ctx->infra_base + ctx->data->regs_ofs->vio_dbg1_offset;
+	vio_dbg0_reg = ctx->base + ctx->data->regs_ofs->vio_dbg0_offset;
+	vio_dbg1_reg = ctx->base + ctx->data->regs_ofs->vio_dbg1_offset;
+	vio_dbg2_reg = ctx->base + ctx->data->regs_ofs->vio_dbg2_offset;
+	vio_dbg3_reg = ctx->base + ctx->data->regs_ofs->vio_dbg3_offset;
 
 	vio_dbgs.vio_dbg0 = readl(vio_dbg0_reg);
 	vio_dbgs.vio_dbg1 = readl(vio_dbg1_reg);
+	if (ctx->data->version >= 2U)
+		vio_dbgs.vio_dbg2 = readl(vio_dbg2_reg);
+	if (ctx->data->version == 3U)
+		vio_dbgs.vio_dbg3 = readl(vio_dbg3_reg);
+
+	if (ctx->data->version == 1U) {
+		/* arch version 1 */
+		bus_id = vio_dbgs.dbg0_bits.mstid;
+		vio_addr = vio_dbgs.vio_dbg1;
+		domain_id = vio_dbgs.dbg0_bits.dmnid;
+		vio_w = vio_dbgs.dbg0_bits.vio_w;
+		vio_r = vio_dbgs.dbg0_bits.vio_r;
+	} else {
+		/* arch version 2 & 3 */
+		bus_id = vio_dbgs.vio_dbg1;
+
+		vio_addr_l = vio_dbgs.vio_dbg2;
+		vio_addr_h = ctx->data->version == 2U ? vio_dbgs.dbg0_bits_ver2.addr_h :
+							vio_dbgs.vio_dbg3;
+		vio_addr = ((u64)vio_addr_h << 32) + vio_addr_l;
+		domain_id = vio_dbgs.dbg0_bits_ver2.dmnid;
+		vio_w = vio_dbgs.dbg0_bits_ver2.vio_w;
+		vio_r = vio_dbgs.dbg0_bits_ver2.vio_r;
+	}
 
 	/* Print violation information */
-	if (vio_dbgs.dbg0_bits.vio_w)
+	if (vio_w)
 		dev_info(ctx->dev, "Write Violation\n");
-	else if (vio_dbgs.dbg0_bits.vio_r)
+	else if (vio_r)
 		dev_info(ctx->dev, "Read Violation\n");
 
-	dev_info(ctx->dev, "Bus ID:0x%x, Dom ID:0x%x, Vio Addr:0x%x\n",
-		 vio_dbgs.dbg0_bits.mstid, vio_dbgs.dbg0_bits.dmnid,
-		 vio_dbgs.vio_dbg1);
+	dev_info(ctx->dev, "Bus ID:0x%x, Dom ID:0x%x, Vio Addr:0x%llx\n",
+		 bus_id, domain_id, vio_addr);
 }
 
 /*
@@ -209,7 +255,8 @@ static irqreturn_t devapc_violation_irq(int irq_number, void *data)
  */
 static void start_devapc(struct mtk_devapc_context *ctx)
 {
-	writel(BIT(31), ctx->infra_base + ctx->data->regs_ofs->apc_con_offset);
+
+	writel(BIT(31), ctx->base + ctx->data->regs_ofs->apc_con_offset);
 
 	mask_module_irq(ctx, false);
 }
@@ -221,28 +268,60 @@ static void stop_devapc(struct mtk_devapc_context *ctx)
 {
 	mask_module_irq(ctx, true);
 
-	writel(BIT(2), ctx->infra_base + ctx->data->regs_ofs->apc_con_offset);
+	writel(BIT(2), ctx->base + ctx->data->regs_ofs->apc_con_offset);
 }
 
-static const struct mtk_devapc_regs_ofs devapc_regs_ofs_mt6779 = {
+static const struct mtk_devapc_regs_ofs devapc_regs_ofs_ver1 = {
+	.vio_mask_offset = 0x0,
+	.vio_sta_offset = 0x400,
+	.vio_dbg0_offset = 0x900,
+	.vio_dbg1_offset = 0x904,
+	.apc_con_offset = 0xf00,
+	.vio_shift_sta_offset = 0xf10,
+	.vio_shift_sel_offset = 0xf14,
+	.vio_shift_con_offset = 0xf20,
+};
+
+static const struct mtk_devapc_regs_ofs devapc_regs_ofs_ver2 = {
 	.vio_mask_offset = 0x0,
 	.vio_sta_offset = 0x400,
 	.vio_dbg0_offset = 0x900,
 	.vio_dbg1_offset = 0x904,
-	.apc_con_offset = 0xF00,
-	.vio_shift_sta_offset = 0xF10,
-	.vio_shift_sel_offset = 0xF14,
-	.vio_shift_con_offset = 0xF20,
+	.vio_dbg2_offset = 0x908,
+	.apc_con_offset = 0xf00,
+	.vio_shift_sta_offset = 0xf20,
+	.vio_shift_sel_offset = 0xf30,
+	.vio_shift_con_offset = 0xf10,
+};
+
+static const struct mtk_devapc_regs_ofs devapc_regs_ofs_ver3 = {
+	.vio_mask_offset = 0x0,
+	.vio_sta_offset = 0x400,
+	.vio_dbg0_offset = 0x900,
+	.vio_dbg1_offset = 0x904,
+	.vio_dbg2_offset = 0x908,
+	.vio_dbg3_offset = 0x90c,
+	.apc_con_offset = 0xf00,
+	.vio_shift_sta_offset = 0xf20,
+	.vio_shift_sel_offset = 0xf30,
+	.vio_shift_con_offset = 0xf10,
 };
 
 static const struct mtk_devapc_data devapc_mt6779 = {
-	.vio_idx_num = 511,
-	.regs_ofs = &devapc_regs_ofs_mt6779,
+	.version = 1,
+	.default_vio_idx_num = 511,
+	.regs_ofs = &devapc_regs_ofs_ver1,
 };
 
 static const struct mtk_devapc_data devapc_mt8186 = {
-	.vio_idx_num = 519,
-	.regs_ofs = &devapc_regs_ofs_mt6779,
+	.version = 1,
+	.default_vio_idx_num = 519,
+	.regs_ofs = &devapc_regs_ofs_ver1,
+};
+
+static const struct mtk_devapc_data devapc_mt8189 = {
+	.version = 3,
+	.regs_ofs = &devapc_regs_ofs_ver3,
 };
 
 static const struct of_device_id mtk_devapc_dt_match[] = {
@@ -252,6 +331,9 @@ static const struct of_device_id mtk_devapc_dt_match[] = {
 	}, {
 		.compatible = "mediatek,mt8186-devapc",
 		.data = &devapc_mt8186,
+	}, {
+		.compatible = "mediatek,mt8189-devapc",
+		.data = &devapc_mt8189,
 	}, {
 	},
 };
@@ -274,9 +356,24 @@ static int mtk_devapc_probe(struct platform_device *pdev)
 	ctx->data = of_device_get_match_data(&pdev->dev);
 	ctx->dev = &pdev->dev;
 
-	ctx->infra_base = of_iomap(node, 0);
-	if (!ctx->infra_base)
+	ctx->base = of_iomap(node, 0);
+	if (!ctx->base) {
+		dev_err(ctx->dev, "Failed to map devapc registers\n");
 		return -EINVAL;
+	}
+
+	/*
+	 * Set effective vio_idx_num from default value.
+	 * If vio_idx_num is 0, get the info from DT.
+	 */
+	ctx->vio_idx_num = ctx->data->default_vio_idx_num;
+	if (ctx->vio_idx_num == 0)
+		if (of_property_read_u32(node,
+					 "vio-idx-num",
+					 &ctx->vio_idx_num)) {
+			ret = -EINVAL;
+			goto err;
+		}
 
 	devapc_irq = irq_of_parse_and_map(node, 0);
 	if (!devapc_irq) {
@@ -314,7 +411,7 @@ static int mtk_devapc_probe(struct platform_device *pdev)
 	return 0;
 
 err:
-	iounmap(ctx->infra_base);
+	iounmap(ctx->base);
 	return ret;
 }
 
@@ -326,7 +423,7 @@ static void mtk_devapc_remove(struct platform_device *pdev)
 
 	clk_disable_unprepare(ctx->infra_clk);
 
-	iounmap(ctx->infra_base);
+	iounmap(ctx->base);
 }
 
 static struct platform_driver mtk_devapc_driver = {
-- 
2.45.2



^ permalink raw reply related

* [PATCH v3 1/6] soc: mediatek: mtk-devapc: refine devapc interrupt handler
From: Xiaoshun Xu @ 2026-04-16  3:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Xiaoshun Xu
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	Sirius Wang, Vince-wl Liu, Project_Global_Chrome_Upstream_Group
In-Reply-To: <20260416031231.2932493-1-xiaoshun.xu@mediatek.com>

Because the violation IRQ uses a while loop, it might cause the
system to remain in the interrupt handler indefinitely. We are
currently optimizing this part of the process to handle only 20
violations for debug violation issues, and then exit the loop

Signed-off-by: Xiaoshun Xu <xiaoshun.xu@mediatek.com>
---
 drivers/soc/mediatek/mtk-devapc.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
index f54c966138b5..c9e1401315ad 100644
--- a/drivers/soc/mediatek/mtk-devapc.c
+++ b/drivers/soc/mediatek/mtk-devapc.c
@@ -12,6 +12,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
 
+#define MAX_VIO_NUM 20
 #define VIO_MOD_TO_REG_IND(m)	((m) / 32)
 #define VIO_MOD_TO_REG_OFF(m)	((m) % 32)
 
@@ -188,13 +189,18 @@ static void devapc_extract_vio_dbg(struct mtk_devapc_context *ctx)
  */
 static irqreturn_t devapc_violation_irq(int irq_number, void *data)
 {
+	u32 vio_num = 0;
 	struct mtk_devapc_context *ctx = data;
 
-	while (devapc_sync_vio_dbg(ctx))
+	mask_module_irq(ctx, true);
+
+	for (vio_num = 0; (vio_num < MAX_VIO_NUM) && (devapc_sync_vio_dbg(ctx)); ++vio_num)
 		devapc_extract_vio_dbg(ctx);
 
 	clear_vio_status(ctx);
 
+	mask_module_irq(ctx, false);
+
 	return IRQ_HANDLED;
 }
 
-- 
2.45.2



^ permalink raw reply related

* [PATCH v3 2/6] soc: mediatek: mtk-devapc: refine DEVAPC clock control
From: Xiaoshun Xu @ 2026-04-16  3:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Xiaoshun Xu
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	Sirius Wang, Vince-wl Liu, Project_Global_Chrome_Upstream_Group
In-Reply-To: <20260416031231.2932493-1-xiaoshun.xu@mediatek.com>

Because the new DEVAPC design, DEVAPC clock is controlled by
HW power domains, the control flow of DEVAPC clock is not
necessary, but to maintain compatibility with legacy ICs,
keep this part of code.

Signed-off-by: Xiaoshun Xu <xiaoshun.xu@mediatek.com>
---
 drivers/soc/mediatek/mtk-devapc.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
index c9e1401315ad..f54e310791e5 100644
--- a/drivers/soc/mediatek/mtk-devapc.c
+++ b/drivers/soc/mediatek/mtk-devapc.c
@@ -284,16 +284,28 @@ static int mtk_devapc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	ctx->infra_clk = devm_clk_get_enabled(&pdev->dev, "devapc-infra-clock");
+	/*
+	 * The new design of DAPC clock is controlled by HW power domains,
+	 * making it unnecessary to provide the clock control driver.
+	 */
+	ctx->infra_clk = devm_clk_get_optional(&pdev->dev, "devapc-infra-clock");
 	if (IS_ERR(ctx->infra_clk)) {
-		ret = -EINVAL;
-		goto err;
+		dev_err(ctx->dev, "Cannot get devapc clock from CCF\n");
+		ctx->infra_clk = NULL;
+	} else {
+		if (clk_prepare_enable(ctx->infra_clk)) {
+			ret = -EINVAL;
+			goto err;
+		}
 	}
 
 	ret = devm_request_irq(&pdev->dev, devapc_irq, devapc_violation_irq,
-			       IRQF_TRIGGER_NONE, "devapc", ctx);
-	if (ret)
+			       IRQF_TRIGGER_NONE | IRQF_SHARED, "devapc", ctx);
+	if (ret) {
+		if (ctx->infra_clk)
+			clk_disable_unprepare(ctx->infra_clk);
 		goto err;
+	}
 
 	platform_set_drvdata(pdev, ctx);
 
@@ -311,6 +323,9 @@ static void mtk_devapc_remove(struct platform_device *pdev)
 	struct mtk_devapc_context *ctx = platform_get_drvdata(pdev);
 
 	stop_devapc(ctx);
+
+	clk_disable_unprepare(ctx->infra_clk);
+
 	iounmap(ctx->infra_base);
 }
 
-- 
2.45.2



^ permalink raw reply related

* [PATCH v3 0/6] soc: mediatek: Add devapc support
From: Xiaoshun Xu @ 2026-04-16  3:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Xiaoshun Xu
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	Sirius Wang, Vince-wl Liu, Project_Global_Chrome_Upstream_Group,
	Xiaoshun Xu

From: Xiaoshun Xu <xiaoshun.xu@mediatek.corp-partner.google.com>

Based on tag: next-20260415, linux-next/master

This series of patches add support for Mediatek devapc of MT8189 and
MT8196 soc.

Xiaoshun Xu (6):
  soc: mediatek: mtk-devapc: refine devapc interrupt handler
  soc: mediatek: mtk-devapc: refine DEVAPC clock control
  soc: mediatek: mtk-devapc: Add support for MT8189 DEVAPC
  dt-bindings: soc: mediatek: devapc: Add bindings for MT8189
  soc: mediatek: mtk-devapc: Add support for MT8196 DEVAPC
  dt-bindings: soc: mediatek: devapc: Add bindings for MT8196

Changes in v3:
  - Add support for MT8196 devapc
  - Updated yaml for dt-bindings

Changes in v2:
  - Updated cover letter subject
  - Updated yaml for dt-bindings
  - Add support for MT8189 devapc
  - Refine devapc clock control flow
  - Refine devapc interrupt handler

Changes in v1:
  - Add support for MT8189 devapc
  - Updated yaml for MT8189

 .../bindings/soc/mediatek/devapc.yaml         |  11 +-
 drivers/soc/mediatek/mtk-devapc.c             | 197 ++++++++++++++----
 2 files changed, 168 insertions(+), 40 deletions(-)

-- 
2.45.2



^ permalink raw reply

* Re: [Question mpam mpam/snapshot+extras/v6.18-rc1] Question with Configuring iommu_group in 'task'
From: Zeng Heng @ 2026-04-16  3:02 UTC (permalink / raw)
  To: Ben Horgan, James Morse
  Cc: Qinxin Xia, amitsinght, baisheng.gao, baolin.wang, carl,
	dave.martin, david, dfustini, fenghuay, gshan, jonathan.cameron,
	kobak, lcherian, linux-arm-kernel, linux-kernel, peternewman,
	punit.agrawal, quic_jiles, reinette.chatre, rohit.mathew, scott,
	sdonthineni, xhao, Linuxarm
In-Reply-To: <f800f0d5-7a00-4dad-95fe-a2aac2ece5ef@arm.com>



On 2026/4/15 20:42, Ben Horgan wrote:
> Hi Zeng,
> 
> On 4/15/26 02:27, Zeng Heng wrote:
>> Hi Ben,
>>
>> On 2026/4/13 23:02, Ben Horgan wrote:
>>> Hi Qinxin,
>>>
>>> On 4/3/26 03:44, Qinxin Xia wrote:
>>>>
>>>>
>>>> On 2026/3/27 18:47:49, Ben Horgan <ben.horgan@arm.com> wrote:
>>>>> Hi Qinxin,
>>>>>
>>>>> On 3/27/26 10:21, Qinxin Xia wrote:
>>>>>>
>>>>>> Hello everyone!
>>>>>>
>>>>>> In earlier versions, mpam supports the configuration of iommu_groups.
>>>>>>
>>>>>>     823 static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of,
>>>>>>     824                                     char *buf, size_t nbytes,
>>>>>> loff_t off)
>>>>>>     825 {
>>>>>>     826         struct rdtgroup *rdtgrp;
>>>>>>     827         int iommu_group_id;
>>>>>>     828         bool is_iommu;
>>>>>>     829         char *pid_str;
>>>>>>     830         int ret = 0;
>>>>>>     831         pid_t pid;
>>>>>>     832
>>>>>>     833         rdtgrp = rdtgroup_kn_lock_live(of->kn);
>>>>>>     834         if (!rdtgrp) {
>>>>>>     835                 rdtgroup_kn_unlock(of->kn);
>>>>>>     836                 return -ENOENT;
>>>>>>     837         }
>>>>>>     838         rdt_last_cmd_clear();
>>>>>>     839
>>>>>>     840         if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED ||
>>>>>>     841             rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
>>>>>>     842                 ret = -EINVAL;
>>>>>>     843                 rdt_last_cmd_puts("Pseudo-locking in progress\n");
>>>>>>     844                 goto unlock;
>>>>>>     845         }
>>>>>>     846
>>>>>>     847         while (buf && buf[0] != '\0' && buf[0] != '\n') {
>>>>>>     848                 pid_str = strim(strsep(&buf, ","));
>>>>>>     849
>>>>>>     850                 is_iommu = string_is_iommu_group(pid_str, &iommu_group_id);
>>>>>>
>>>>>> What puzzles me is why we would put it under 'task'—this seems a little
>>>>>>     strange to users.It seems they are not related.Why don't we add a new
>>>>>> interface like 'iommu'?
>>>>>
>>>>> I think it is likely that this interface would change if upstream support is added.
>>>>>
>>>>
>>>> I have done some work in this direction before, and I will release an
>>>> RFC later for further discussion.:-)
>>>
>>> Looking forward to seeing it.
>>>
>>> Ben
>>>
>>
>> Following the current SMMU approach, I've submitted several bugfix
>> patches for the MPAM driver, but haven't received any review feedback
>> yet.
>>
>> To avoid these being overlooked, I'd like to kindly remind to take a
>> look:
>> v2: https://lore.kernel.org/all/20260414032610.1523958-1-zengheng4@huawei.com/
>> v1: https://lore.kernel.org/all/20251107063300.1580046-1-zengheng4@huawei.com/
>>
>> Additionally, I'd like to check on the status of this branch — is it
>> still actively maintained? It would be helpful to understand the future
>> plans for MPAM development.
> 
> The MPAM snapshot and extras branches are no longer maintained. Work on these has stopped so that we can focus on
> upstream. Apologies for not making this clear earlier.
> 


Ack. If the extras branch scheme mentioned above is rebased onto
upstream, these bugfix patches would remain applicable and worth
reviewing.


Best regards,
Zeng Heng


^ permalink raw reply

* RE: [PATCH v2] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Zhipeng Wang @ 2026-04-16  1:59 UTC (permalink / raw)
  To: Frank Li
  Cc: ulfh@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de,
	festevam@gmail.com, linux-pm@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, Xuegang Liu, Jindong Yue
In-Reply-To: <ad83MtdMP4rci3Ya@lizhi-Precision-Tower-5810>

> On Mon, Apr 13, 2026 at 02:30:49PM +0900, Zhipeng Wang wrote:
> > Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate to
> > allow building as loadable modules.
> >
> > Add prompt strings to make these options visible and configurable in
> > menuconfig, keeping them enabled by default on appropriate platforms.
> >
> > Also remove the IMX_GPCV2_PM_DOMAINS dependency from
> IMX9_BLK_CTRL.
> > This dependency was incorrect from the beginning - i.MX93 uses a
> 
> s/-/because
> 
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> 

Hi Frank,

Thank you! v3 sent.

BRs,
Zhipeng
> > different power domain architecture compared to i.MX8M series:
> >
> > - i.MX8M uses GPCv2 (General Power Controller v2) for power domain
> >   management, hence IMX8M_BLK_CTRL correctly depends on it.
> >
> > - i.MX93 uses BLK_CTRL directly without GPCv2. The hardware doesn't
> >   have GPCv2 at all.
> >
> > Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
> > ---
> >  drivers/pmdomain/imx/Kconfig | 11 +++++++----
> >  1 file changed, 7 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/pmdomain/imx/Kconfig
> > b/drivers/pmdomain/imx/Kconfig index 00203615c65e..9168d183b0c5
> 100644
> > --- a/drivers/pmdomain/imx/Kconfig
> > +++ b/drivers/pmdomain/imx/Kconfig
> > @@ -10,15 +10,18 @@ config IMX_GPCV2_PM_DOMAINS
> >  	default y if SOC_IMX7D
> >
> >  config IMX8M_BLK_CTRL
> > -	bool
> > -	default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
> > +	tristate "i.MX8M BLK CTRL driver"
> > +	depends on SOC_IMX8M
> > +	depends on IMX_GPCV2_PM_DOMAINS
> >  	depends on PM_GENERIC_DOMAINS
> >  	depends on COMMON_CLK
> > +	default y
> >
> >  config IMX9_BLK_CTRL
> > -	bool
> > -	default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
> > +	tristate "i.MX93 BLK CTRL driver"
> > +	depends on SOC_IMX9
> >  	depends on PM_GENERIC_DOMAINS
> > +	default y
> >
> >  config IMX_SCU_PD
> >  	bool "IMX SCU Power Domain driver"
> > --
> > 2.34.1
> >


^ permalink raw reply

* [PATCH v3] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Zhipeng Wang @ 2026-04-16  1:56 UTC (permalink / raw)
  To: ulfh, Frank.Li, s.hauer
  Cc: kernel, festevam, linux-pm, imx, linux-arm-kernel, linux-kernel,
	xuegang.liu, jindong.yue

Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate
to allow building as loadable modules.

Add prompt strings to make these options visible and configurable
in menuconfig, keeping them enabled by default on appropriate platforms.

Also remove the IMX_GPCV2_PM_DOMAINS dependency from IMX9_BLK_CTRL.
This dependency was incorrect from the beginning because i.MX93 uses a
different power domain architecture compared to i.MX8M series:

- i.MX8M uses GPCv2 (General Power Controller v2) for power domain
  management, hence IMX8M_BLK_CTRL correctly depends on it.

- i.MX93 uses BLK_CTRL directly without GPCv2. The hardware doesn't
  have GPCv2 at all.

Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/pmdomain/imx/Kconfig | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/pmdomain/imx/Kconfig b/drivers/pmdomain/imx/Kconfig
index 00203615c65e..9168d183b0c5 100644
--- a/drivers/pmdomain/imx/Kconfig
+++ b/drivers/pmdomain/imx/Kconfig
@@ -10,15 +10,18 @@ config IMX_GPCV2_PM_DOMAINS
 	default y if SOC_IMX7D
 
 config IMX8M_BLK_CTRL
-	bool
-	default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
+	tristate "i.MX8M BLK CTRL driver"
+	depends on SOC_IMX8M
+	depends on IMX_GPCV2_PM_DOMAINS
 	depends on PM_GENERIC_DOMAINS
 	depends on COMMON_CLK
+	default y
 
 config IMX9_BLK_CTRL
-	bool
-	default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
+	tristate "i.MX93 BLK CTRL driver"
+	depends on SOC_IMX9
 	depends on PM_GENERIC_DOMAINS
+	default y
 
 config IMX_SCU_PD
 	bool "IMX SCU Power Domain driver"
-- 
2.34.1



^ permalink raw reply related

* RE: [PATCH v29 2/4] dt-bindings: i2c: ast2600-i2c.yaml: Add global-regs properties
From: Ryan Chen @ 2026-04-16  1:38 UTC (permalink / raw)
  To: Conor Dooley
  Cc: jk@codeconstruct.com.au, andriy.shevchenko@linux.intel.com,
	Andi Shyti, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Joel Stanley, Andrew Jeffery, Benjamin Herrenschmidt, Rayn Chen,
	Philipp Zabel, linux-i2c@vger.kernel.org,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org,
	openbmc@lists.ozlabs.org
In-Reply-To: <20260415-unrushed-collected-562130070d8b@spud>

> Subject: Re: [PATCH v29 2/4] dt-bindings: i2c: ast2600-i2c.yaml: Add global-regs
> properties
> 
> On Wed, Apr 15, 2026 at 01:14:03PM +0800, Ryan Chen wrote:
> > Add the aspeed,global-regs phandle to reference the AST2600 global
> > registers syscon node, containing the SoC-common I2C register set.
> >
> > These properties apply only to the AST2600 binding. Legacy DTs remain
> > unchanged.
> >
> > Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
> 
> I hate to do it to you on v29, but can you please explain what this
> "soc-common i2c register set" actually is/does in your commit message.

Thanks your review.
The common means this global register is common register have common
register control used by all i2c bus.
Such like register layout mode (new vs. legacy) and shared base clock dividers.

> The patch seems fine, so with that
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> pw-bot: not-applicable
> 
> > ---
> > Changes in v29:
> > - remove aspeed,enable-dma properties.
> >
> > Changes in v28:
> > - update commit message correspond with aspeed,enable-dma.
> > - remove aspeed,transfer-mode and add aspeed,enable-dma property and
> >   description.
> > - Fix aspeed,enable-dma description to reflect hardware capability rather
> >   than software behavior
> >
> > Changes in v27:
> > - change aspeed,transfer-mode to aspeed,enable-dma.
> > ---
> >  Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml | 7
> > +++++++
> >  1 file changed, 7 insertions(+)
> >
> > diff --git
> > a/Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml
> > b/Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml
> > index de2c359037da..0c769efb76a5 100644
> > --- a/Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml
> > +++ b/Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml
> > @@ -37,6 +37,12 @@ properties:
> >    resets:
> >      maxItems: 1
> >
> > +  aspeed,global-regs:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description:
> > +      Phandle reference to the i2c global syscon node, containing the
> > +      SoC-common i2c register set.
> > +
> >  required:
> >    - reg
> >    - compatible
> > @@ -59,4 +65,5 @@ examples:
> >          resets = <&syscon ASPEED_RESET_I2C>;
> >          clock-frequency = <100000>;
> >          interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
> > +        aspeed,global-regs = <&i2c_global>;
> >      };
> >
> > --
> > 2.34.1
> >


^ permalink raw reply

* Re: [PATCH v3 2/2] mmc: dw_mmc: exynos: increase DMA threshold value for exynos7870
From: Shawn Lin @ 2026-04-16  0:29 UTC (permalink / raw)
  To: Kaustabh Chakraborty, Ulf Hansson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jaehoon Chung,
	Krzysztof Kozlowski, Alim Akhtar
  Cc: shawn.lin, linux-mmc, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc
In-Reply-To: <20260415-dwmmc-dma-thr-v3-2-31014d36b6ee@disroot.org>

在 2026/04/15 星期三 23:02, Kaustabh Chakraborty 写道:
> Exynos 7870 compatible controllers, such as SDIO ones are not able to
> perform DMA transfers for small sizes of data (~16 to ~512 bytes),
> resulting in cache issues in subsequent transfers. Increase the DMA
> transfer threshold to 512 to allow the shorter transfers to take place,
> bypassing DMA.
> 

Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>

> Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
> ---
>   drivers/mmc/host/dw_mmc-exynos.c | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
> index 261344d3a8cfe..4b76b997ddc15 100644
> --- a/drivers/mmc/host/dw_mmc-exynos.c
> +++ b/drivers/mmc/host/dw_mmc-exynos.c
> @@ -141,6 +141,7 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host)
>   		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU) {
>   		/* Quirk needed for certain Exynos SoCs */
>   		host->quirks |= DW_MMC_QUIRK_FIFO64_32;
> +		host->dma_threshold = 512;
>   	}
>   
>   	if (priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) {
> 


^ permalink raw reply

* Re: [PATCH v3 1/2] mmc: dw_mmc: implement option for configuring DMA threshold
From: Shawn Lin @ 2026-04-16  0:27 UTC (permalink / raw)
  To: Kaustabh Chakraborty, Ulf Hansson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jaehoon Chung,
	Krzysztof Kozlowski, Alim Akhtar
  Cc: shawn.lin, linux-mmc, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc
In-Reply-To: <20260415-dwmmc-dma-thr-v3-1-31014d36b6ee@disroot.org>


在 2026/04/15 星期三 23:02, Kaustabh Chakraborty 写道:
> Some controllers, such as certain Exynos SDIO ones, are unable to
> perform DMA transfers of small amount of bytes properly. Following the
> device tree schema, implement the property to define the DMA transfer
> threshold (from a hard coded value of 16 bytes) so that lesser number of
> bytes can be transferred safely skipping DMA in such controllers. The
> value of 16 bytes stays as the default for controllers which do not
> define it. This value can be overridden by implementation-specific init
> sequences.

Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>

> 
> Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
> ---
>   drivers/mmc/host/dw_mmc.c | 4 ++--
>   drivers/mmc/host/dw_mmc.h | 2 ++
>   2 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 20193ee7b73eb..3b4157f34d11f 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -40,7 +40,6 @@
>   				 SDMMC_INT_RESP_ERR | SDMMC_INT_HLE)
>   #define DW_MCI_ERROR_FLAGS	(DW_MCI_DATA_ERROR_FLAGS | \
>   				 DW_MCI_CMD_ERROR_FLAGS)
> -#define DW_MCI_DMA_THRESHOLD	16
>   
>   #define DW_MCI_FREQ_MAX	200000000	/* unit: HZ */
>   #define DW_MCI_FREQ_MIN	100000		/* unit: HZ */
> @@ -821,7 +820,7 @@ static int dw_mci_pre_dma_transfer(struct dw_mci *host,
>   	 * non-word-aligned buffers or lengths. Also, we don't bother
>   	 * with all the DMA setup overhead for short transfers.
>   	 */
> -	if (data->blocks * data->blksz < DW_MCI_DMA_THRESHOLD)
> +	if (data->blocks * data->blksz < host->dma_threshold)
>   		return -EINVAL;
>   
>   	if (data->blksz & 3)
> @@ -3185,6 +3184,7 @@ struct dw_mci *dw_mci_alloc_host(struct device *dev)
>   	host = mmc_priv(mmc);
>   	host->mmc = mmc;
>   	host->dev = dev;
> +	host->dma_threshold = 16;
>   
>   	return host;
>   }
> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
> index 42e58be74ce09..f29d40158dc59 100644
> --- a/drivers/mmc/host/dw_mmc.h
> +++ b/drivers/mmc/host/dw_mmc.h
> @@ -107,6 +107,7 @@ struct dw_mci_dma_slave {
>    * @ciu_clk: Pointer to card interface unit clock instance.
>    * @fifo_depth: depth of FIFO.
>    * @data_addr_override: override fifo reg offset with this value.
> + * @dma_threshold: data threshold value in bytes to carry out a DMA transfer.
>    * @wm_aligned: force fifo watermark equal with data length in PIO mode.
>    *	Set as true if alignment is needed.
>    * @data_shift: log2 of FIFO item size.
> @@ -163,6 +164,7 @@ struct dw_mci {
>   	void __iomem		*regs;
>   	void __iomem		*fifo_reg;
>   	u32			data_addr_override;
> +	u32			dma_threshold;
>   	bool			wm_aligned;
>   
>   	struct scatterlist	*sg;
> 


^ permalink raw reply

* Re: [PATCH net-next] net: stmmac: enable RPS and RBU interrupts
From: Russell King (Oracle) @ 2026-04-16  0:02 UTC (permalink / raw)
  To: Sam Edwards
  Cc: Jakub Kicinski, Andrew Lunn, Alexandre Torgue, Andrew Lunn,
	David S. Miller, Eric Dumazet,
	moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
	linux-stm32, Linux Network Development Mailing List, Paolo Abeni
In-Reply-To: <CAH5Ym4j3GePEMEMmg1Z27gYfQ0N8Sc1BMW1rnvNZ4aLQ+cfFyQ@mail.gmail.com>

On Wed, Apr 15, 2026 at 01:50:53PM -0700, Sam Edwards wrote:
> On Wed, Apr 15, 2026 at 12:37 PM Russell King (Oracle)
> <linux@armlinux.org.uk> wrote:
> >
> > It's not a question about how I define RBU - this is defined by Synopsys
> > and I'm using it *exactly* that way as stated in the documentation.
> >
> > "This bit indicates that the host owns the Next Descriptor in the
> > Receive List and the DMA cannot acquire it. The Receive Process is
> > suspended. ... This bit is set only when the previous Receive
> > Descriptor is owned by the DMA."
> >
> > In other words, DMA has processed the previous receive descriptor which
> > _was_ owned by the hardware, written back to clear the OWN bit, and
> > then fetches the next descriptor and finds that the OWN bit is also
> > clear.
> 
> I'm only trying to leave open the possibility that the Synopsys
> technical writer and the hardware implementation team weren't
> communicating clearly. We already have a situation where RPS isn't
> behaving as documented (even if that's likely just hardware
> misconfiguration), so while I'm currently pretty sure RBU carries no
> other (actual) meaning than "DMA caught up to OWN=0," I'm only about
> 75% confident.

It doesn't make sense for RPS to be set though. RPS is "Receive Process
Stopped" and it's documented as being raised when the receive process
enters the stopped state.

If we look at the DMA Debug Status 0 register at 0x100c, then this
gives us a four bit bitfield for channels 0, 1 and 2. Further channels
are in 0x1010. I've added code to dump these when RBU occurs:

dwc-eth-dwmac 2490000.ethernet eth0: debug status: 0x00006400 0x00000000

bits 11:8 are RPS0, which indiciates that the DMA channel 0 receive
process state is "Suspended (Rx Descriptor Unavailable)". If this were
0, then it would be "Stopped (Reset or Stop Receive Command issued)".

So, RPS isn't being raised because the process state isn't entering
the stopped state, which makes sense - because we haven't issued a
stop command, nor have we caused a reset, and the documented recovery
from this condition is to merely advance the tail pointer, rather than
issuing a command to re-start the receive process.

When this is done (because stmmac_rx() continues to periodically run
because of NAPI) RPS0 does change back to 3 "Running (Waiting for Rx
packet)" but it seems that although there are packets waiting to be
written out, that never happens (the Queue 0 Receive Debug register
indicates that there are packets in the receive queue, the receive
queue fill level is above the flow control activate threshold, and
the MAC itself hammers the network with pause frames as a result.)

Thus, I think that the fact that RPS isn't being signalled is entirely
reasonable and consistent with the available documentation.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!


^ permalink raw reply

* Re: [PATCH v7 6/6] arm64: dts: rockchip: Add Orange Pi 5 Pro board support
From: Dennis Gilmore @ 2026-04-15 23:34 UTC (permalink / raw)
  To: Alexey Charkov
  Cc: Andrew Lunn, Andrzej Hajda, Chaoyi Chen, Conor Dooley,
	David Airlie, devicetree, dri-devel, FUKAUMI Naoki,
	Heiko Stuebner, Hsun Lai, Jernej Skrabec, Jimmy Hon, John Clark,
	Jonas Karlman, Krzysztof Kozlowski, Laurent Pinchart,
	linux-arm-kernel, linux-kernel, linux-rockchip, Maarten Lankhorst,
	Maxime Ripard, Michael Opdenacker, Michael Riesch, Mykola Kvach,
	Neil Armstrong, Peter Robinson, Quentin Schulz, Robert Foss,
	Rob Herring, Simona Vetter, Thomas Zimmermann
In-Reply-To: <CABjd4YxfeCfRUneZfFx31WmQOexO0gcH8yHPQmRY38GKNk=Ztg@mail.gmail.com>

Hi Alexey,

On Wed, Apr 15, 2026 at 3:57 AM Alexey Charkov <alchark@gmail.com> wrote:
>
> On Wed, Apr 15, 2026 at 1:41 AM Dennis Gilmore <dennis@ausil.us> wrote:
> >
> > Add device tree for the Xunlong Orange Pi 5 Pro (RK3588S).
> >
> > - eMMC module, you can optionally solder a SPI NOR in place and turn
> >  off the eMMC
> > - PCIe-attached NIC (pcie2x1l1)
> > - PCIe NVMe slot (pcie2x1l2)
>
> Hi Dennis,
>
> Sashiko noticed [1] that the controller names here do not match the
> nodes/comments you have in the patch body - which ones are correct?
>
> [1] https://sashiko.dev/#/patchset/20260414214104.1363987-1-dennis%40ausil.us

The ones in the body are correct. will fix

> > - AP6256 WiFi (BCM43456) via SDIO with mmc-pwrseq
> > - BCM4345C5 Bluetooth
> > - es8388 audio
> > - USB 2.0 and USB 3.0
> > - Two HDMI ports, the second is connected to the SoC's DP controller
> >   driven through a Lontium LT8711UXD bridge.
> >
> > Vendors schematics are available at:
> > https://drive.google.com/file/d/1qs1DratHuh7C6J6MEtQIwUsiSrg8qgTi/view
> >
> > Signed-off-by: Dennis Gilmore <dennis@ausil.us>
> > ---
> >  arch/arm64/boot/dts/rockchip/Makefile         |   1 +
> >  .../dts/rockchip/rk3588s-orangepi-5-pro.dts   | 442 ++++++++++++++++++
> >  2 files changed, 443 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
> > index 4d384f153c13..c99dca2ae9e7 100644
> > --- a/arch/arm64/boot/dts/rockchip/Makefile
> > +++ b/arch/arm64/boot/dts/rockchip/Makefile
> > @@ -214,6 +214,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6c.dtb
> >  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-odroid-m2.dtb
> >  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-5.dtb
> >  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-5b.dtb
> > +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-5-pro.dtb
> >  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-cm5-base.dtb
> >  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-radxa-cm5-io.dtb
> >  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-roc-pc.dtb
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts
> > new file mode 100644
> > index 000000000000..61462c66753d
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts
> > @@ -0,0 +1,442 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +
> > +/dts-v1/;
> > +
> > +#include "rk3588s-orangepi-5.dtsi"
> > +
> > +/ {
> > +       model = "Xunlong Orange Pi 5 Pro";
> > +       compatible = "xunlong,orangepi-5-pro", "rockchip,rk3588s";
> > +
> > +       aliases {
> > +               mmc0 = &sdhci;
> > +               mmc1 = &sdmmc;
> > +               mmc2 = &sdio;
> > +       };
> > +
> > +       hdmi1-con {
> > +               compatible = "hdmi-connector";
> > +               label = "HDMI1 OUT";
> > +               type = "a";
> > +
> > +               port {
> > +                       hdmi1_con_in: endpoint {
> > +                               remote-endpoint = <&lt8711uxd_out>;
> > +                       };
> > +               };
> > +       };
> > +
> > +       lt8711uxd {
>
> Please use a generic node name per DT convention. "hdmi-bridge" perhaps?
>

Will adopt hdmi-bridge

> > +               compatible = "lontium,lt8711uxd";
>
> Don't you want to add "vdd-supply = <&vcc3v3_dp>;" here? It costs you
> nothing, as it's already in the binding and in the driver, and having
> this dependency listed explicitly will let the kernel order the driver
> probes correctly, and also likely let you drop the boot-on/always-on
> annotation from the regulator node.

I will add the supply and test drop the boot-on/always-on

> > +               ports {
> > +                       #address-cells = <1>;
> > +                       #size-cells = <0>;
> > +
> > +                       port@0 {
> > +                               reg = <0>;
> > +
> > +                               lt8711uxd_in: endpoint {
> > +                                       remote-endpoint = <&dp0_out_con>;
> > +                               };
> > +                       };
> > +
> > +                       port@1 {
> > +                               reg = <1>;
> > +
> > +                               lt8711uxd_out: endpoint {
> > +                                       remote-endpoint = <&hdmi1_con_in>;
> > +                               };
> > +                       };
> > +               };
> > +       };
> > +
> > +       analog-sound {
> > +               compatible = "simple-audio-card";
> > +               pinctrl-names = "default";
> > +               pinctrl-0 = <&hp_detect>;
> > +               simple-audio-card,format = "i2s";
> > +               simple-audio-card,hp-det-gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>;
> > +               simple-audio-card,mclk-fs = <256>;
> > +               simple-audio-card,name = "rockchip,es8388";
> > +               simple-audio-card,routing =
> > +                       "Headphones", "LOUT1",
> > +                       "Headphones", "ROUT1",
> > +                       "LINPUT1", "Microphone Jack",
> > +                       "RINPUT1", "Microphone Jack",
> > +                       "LINPUT2", "Onboard Microphone",
> > +                       "RINPUT2", "Onboard Microphone";
> > +               simple-audio-card,widgets =
> > +                       "Microphone", "Microphone Jack",
> > +                       "Microphone", "Onboard Microphone",
> > +                       "Headphone", "Headphones";
> > +
> > +               simple-audio-card,cpu {
> > +                       sound-dai = <&i2s2_2ch>;
> > +               };
> > +
> > +               simple-audio-card,codec {
> > +                       sound-dai = <&es8388>;
> > +                       system-clock-frequency = <12288000>;
> > +               };
> > +       };
> > +
> > +       pwm-leds {
> > +               compatible = "pwm-leds";
> > +
> > +               led-0 {
> > +                       color = <LED_COLOR_ID_BLUE>;
> > +                       function = LED_FUNCTION_STATUS;
> > +                       linux,default-trigger = "heartbeat";
> > +                       max-brightness = <255>;
> > +                       pwms = <&pwm15 0 1000000 0>;
> > +               };
> > +
> > +               led-1 {
> > +                       color = <LED_COLOR_ID_GREEN>;
> > +                       function = LED_FUNCTION_ACTIVITY;
> > +                       linux,default-trigger = "heartbeat";
> > +                       max-brightness = <255>;
> > +                       pwms = <&pwm3 0 1000000 0>;
> > +               };
> > +       };
> > +
> > +       fan: pwm-fan {
> > +               compatible = "pwm-fan";
> > +               #cooling-cells = <2>;
> > +               cooling-levels = <0 50 100 150 200 255>;
> > +               fan-supply = <&vcc5v0_sys>;
> > +               pwms = <&pwm2 0 20000000 0>;
> > +       };
> > +
> > +       vcc3v3_dp: regulator-vcc3v3-dp {
> > +               compatible = "regulator-fixed";
> > +               enable-active-high;
> > +               gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_HIGH>;
> > +               pinctrl-names = "default";
> > +               pinctrl-0 = <&dp_bridge_en>;
> > +               regulator-max-microvolt = <3300000>;
> > +               regulator-min-microvolt = <3300000>;
> > +               regulator-name = "vcc3v3_dp";
> > +               regulator-always-on;
> > +               regulator-boot-on;
>
> Please see if you can drop these always-on/boot-on when vdd-supply is
> explicitly listed in the bridge node
>
I have tested removing these with the supply change listed, the HDMI
bridge fails to power on, it does work okay with regulator-always-on
only. It seems necessary to ensure that the bridge is active and that
HPD works. I am open to trying something else to ensure it all works

> > +               vin-supply = <&vcc_3v3_s3>;
> > +       };
> > +
> > +       vcc3v3_phy1: regulator-vcc3v3-phy1 {
> > +               compatible = "regulator-fixed";
> > +               enable-active-high;
> > +               gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
> > +               pinctrl-names = "default";
> > +               pinctrl-0 = <&vcc3v3_phy1_en>;
>
> The board schematics call the pin "Ethernet_EN"

Will rename this

> > +               regulator-max-microvolt = <3300000>;
> > +               regulator-min-microvolt = <3300000>;
> > +               regulator-name = "vcc3v3_phy1";
> > +               startup-delay-us = <50000>;
> > +               vin-supply = <&vcc_3v3_s3>;
> > +       };
> > +
> > +       vcc5v0_otg: regulator-vcc5v0-otg {
> > +               compatible = "regulator-fixed";
> > +               enable-active-high;
> > +               gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
> > +               pinctrl-names = "default";
> > +               pinctrl-0 = <&vcc5v0_otg_en>;
> > +               regulator-max-microvolt = <5000000>;
> > +               regulator-min-microvolt = <5000000>;
> > +               regulator-name = "vcc5v0_otg";
> > +               vin-supply = <&vcc5v0_sys>;
> > +       };
> > +
> > +       sdio_pwrseq: sdio-pwrseq {
> > +               compatible = "mmc-pwrseq-simple";
> > +               clocks = <&hym8563>;
> > +               clock-names = "ext_clock";
> > +               pinctrl-names = "default";
> > +               pinctrl-0 = <&wifi_enable_h>;
> > +               post-power-on-delay-ms = <200>;
> > +               reset-gpios = <&gpio0 RK_PD0 GPIO_ACTIVE_LOW>;
> > +       };
> > +
> > +       typea_con: usb-a-connector {
> > +               compatible = "usb-a-connector";
> > +               data-role = "host";
> > +               label = "USB3 Type-A";
> > +               power-role = "source";
> > +               vbus-supply = <&vcc5v0_otg>;
> > +       };
> > +};
> > +
> > +&dp0 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&dp0m0_pins>;
> > +       status = "okay";
> > +};
> > +
> > +&dp0_in {
> > +       dp0_in_vp1: endpoint {
> > +               remote-endpoint = <&vp1_out_dp0>;
> > +       };
> > +};
> > +
> > +&dp0_out {
> > +       dp0_out_con: endpoint {
> > +               remote-endpoint = <&lt8711uxd_in>;
> > +       };
> > +};
> > +
> > +&i2c1 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&i2c1m4_xfer>;
> > +       status = "okay";
> > +};
> > +
> > +&i2c3 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&i2c3m0_xfer>;
> > +       status = "okay";
> > +
> > +       es8388: audio-codec@11 {
> > +               compatible = "everest,es8388", "everest,es8328";
> > +               reg = <0x11>;
> > +               #sound-dai-cells = <0>;
> > +               AVDD-supply = <&vcca_3v3_s0>;
> > +               DVDD-supply = <&vcca_1v8_s0>;
> > +               HPVDD-supply = <&vcca_3v3_s0>;
> > +               PVDD-supply = <&vcca_1v8_s0>;
> > +               assigned-clock-rates = <12288000>;
> > +               assigned-clocks = <&cru I2S2_2CH_MCLKOUT>;
> > +               clocks = <&cru I2S2_2CH_MCLKOUT>;
> > +               pinctrl-names = "default";
> > +               pinctrl-0 = <&i2s2m1_mclk>;
> > +       };
> > +};
> > +
> > +&i2c4 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&i2c4m3_xfer>;
> > +       status = "okay";
> > +};
> > +
> > +&i2s2_2ch {
> > +       pinctrl-0 = <&i2s2m1_lrck &i2s2m1_sclk
> > +                    &i2s2m1_sdi &i2s2m1_sdo>;
> > +       status = "okay";
> > +};
> > +
> > +&package_thermal {
> > +       polling-delay = <1000>;
> > +
> > +       cooling-maps {
> > +               map0 {
> > +                       trip = <&package_fan0>;
> > +                       cooling-device = <&fan THERMAL_NO_LIMIT 1>;
> > +               };
> > +
> > +               map1 {
> > +                       trip = <&package_fan1>;
> > +                       cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
> > +               };
> > +       };
> > +
> > +       trips {
> > +               package_fan0: package-fan0 {
> > +                       hysteresis = <2000>;
> > +                       temperature = <55000>;
> > +                       type = "active";
> > +               };
> > +
> > +               package_fan1: package-fan1 {
> > +                       hysteresis = <2000>;
> > +                       temperature = <65000>;
> > +                       type = "active";
> > +               };
> > +       };
> > +};
> > +
> > +/* NVMe */
> > +&pcie2x1l1 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&pcie2x1l1_rst &pcie30x1m1_1_clkreqn &pcie30x1m1_1_waken>;
>
> Is there a particular reason to use the GPIO mode for the reset pin,
> rather than the (confusingly named) &pcie30x1m1_1_perstn in line with
> the other two?
There is no particular reason. rk3588-turing-rk1.dtsi is the only
example in the kernel currently doing something similar, and it is
implemented that way there. I agree that the naming is confusing. I
will change it.

> > +       reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
> > +       supports-clkreq;
> > +       vpcie3v3-supply = <&vcc_3v3_s3>;
> > +       status = "okay";
> > +};
> > +
> > +/* NIC */
> > +&pcie2x1l2 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&pcie2x1l2_rst>;
>
> Similar to the above - have you tried the dedicated hardware mode for
> this pin, i.e. &pcie20x1m0_perstn? You are not requesting the
> &pcie20x1m0_clkreqn or &pcie20x1m0_waken either, even though they are
> routed on the board - that will probably bite you if you try
> suspending the board.

I have not, I also have not tried to suspend. Will adopt and test.



> > +       reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
> > +       vpcie3v3-supply = <&vcc3v3_phy1>;
> > +       status = "okay";
> > +};
> > +
> > +&pinctrl {
> > +       bluetooth {
> > +               bt_wake_gpio: bt-wake-pin {
> > +                       rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
>
> If you care about power consumption of the board it's probably better
> to pull this down to make sure the Bluetooth module is predictably in
> a sleep state when not explicitly requested, not floating randomly.
> There is no dedicated pull-up/pull-down on your board.

Will do

> > +               };
> > +
> > +               bt_wake_host_irq: bt-wake-host-irq {
> > +                       rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_down>;
> > +               };
> > +       };
> > +
> > +       dp {
> > +               dp_bridge_en: dp-bridge-en {
> > +                       rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
>
> This pin doesn't have any dedicated pull-up/pull-down on the board, so
> you might end up in a weird power state for the period of time between
> the probing of the pinctrl subsystem and regulators. Better set it to
> &pcfg_pull_down, which matches the power-on-reset default state of
> this pin.

Will do

> > +               };
> > +       };
> > +
> > +       pcie {
> > +               pcie2x1l1_rst: pcie2x1l1-rst {
> > +                       rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
> > +               };
> > +
> > +               pcie2x1l2_rst: pcie2x1l2-rst {
> > +                       rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
> > +               };
> > +
> > +               vcc3v3_phy1_en: vcc3v3-phy1-en {
>
> The schematic calls this pin "Ethernet_EN", so perhaps use that in the
> label and node name for easier reference.

Will do

> > +                       rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
>
> As above: no dedicated pull resistors on the board, better set to
> &pcfg_pull_down in line with POR default.

Will do

> > +               };
> > +       };
> > +
> > +       usb {
> > +               vcc5v0_otg_en: vcc5v0-otg-en {
> > +                       rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
>
> As above: no dedicated pull resistors on the board, better set to
> &pcfg_pull_down in line with POR default.


Will do

> > +               };
> > +       };
> > +
> > +       wlan {
> > +               wifi_enable_h: wifi-enable-h {
> > +                       rockchip,pins = <0 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
>
> As above: no dedicated pull resistors on the board, better set to
> &pcfg_pull_down in line with POR default.

will do

> Best regards,
> Alexey

I appreciate the feedback

Dennis


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox