Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH RFC v2 2/4] drm/i915/display/dp: Adopt dp_connector helpers to expose link training state
From: Jani Nikula @ 2026-06-22  7:28 UTC (permalink / raw)
  To: Kory Maincent, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rodrigo Vivi,
	Joonas Lahtinen, Tvrtko Ursulin, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Luca Ceresoli, Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
	AngeloGioacchino Del Regno, Dmitry Baryshkov, Daniel Stone
  Cc: Thomas Petazzoni, Mark Yacoub, Sean Paul, Manasi Navare,
	Drew Davenport, Louis Chauvet, Luca Ceresoli, dri-devel,
	linux-kernel, intel-gfx, intel-xe, linux-mediatek,
	linux-arm-kernel, Kory Maincent
In-Reply-To: <20260619-feat_link_cap-v2-2-a3dec4c02ad9@bootlin.com>

On Fri, 19 Jun 2026, Kory Maincent <kory.maincent@bootlin.com> wrote:
> Switch the i915 DP connector initialization from
> drm_connector_init_with_ddc() to drm_connector_dp_init_with_ddc(),
> providing the source link capabilities (supported lane counts, link rates
> and DSC support).
>
> Add intel_dp_report_link_train() to collect the negotiated link
> parameters (rate, lane count and DSC enable) and report them via
> drm_dp_set_max_link_params() and drm_dp_set_cur_link_params() once
> link training completes successfully.
>
> Reset the link properties via drm_dp_reset_link_params()
> when the connector is reported as disconnected or when the display device
> is disabled, so the exposed state always reflects the current link status.
>
> Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
> ---
>
> Changes in v2:
> - Remove voltage swing and pre emphasis properties.
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c            | 26 ++++++++++++++++++----
>  .../gpu/drm/i915/display/intel_dp_link_training.c  | 17 ++++++++++++++
>  2 files changed, 39 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index f01a6eed38395..46c06c76952e0 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -6414,8 +6414,10 @@ intel_dp_detect(struct drm_connector *_connector,
>  	drm_WARN_ON(display->drm,
>  		    !drm_modeset_is_locked(&display->drm->mode_config.connection_mutex));
>  
> -	if (!intel_display_device_enabled(display))
> +	if (!intel_display_device_enabled(display)) {
> +		drm_dp_sink_reset_link_caps(_connector);

Gut feeling is that the sprinkling of these around is error prone.

>  		return connector_status_disconnected;
> +	}
>  
>  	if (!intel_display_driver_check_access(display))
>  		return connector->base.status;
> @@ -6465,6 +6467,8 @@ intel_dp_detect(struct drm_connector *_connector,
>  
>  		intel_dp_tunnel_disconnect(intel_dp);
>  
> +		drm_dp_sink_reset_link_caps(_connector);
> +
>  		goto out_unset_edid;
>  	}
>  
> @@ -7240,10 +7244,12 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
>  			struct intel_connector *connector)
>  {
>  	struct intel_display *display = to_intel_display(dig_port);
> +	struct drm_connector_dp_link_caps link_caps;
>  	struct intel_dp *intel_dp = &dig_port->dp;
>  	struct intel_encoder *encoder = &dig_port->base;
>  	struct drm_device *dev = encoder->base.dev;
>  	enum port port = encoder->port;
> +	u32 *rates;
>  	int type;
>  
>  	if (drm_WARN(dev, dig_port->max_lanes < 1,
> @@ -7291,8 +7297,21 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
>  		    type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP",
>  		    encoder->base.base.id, encoder->base.name);
>  
> -	drm_connector_init_with_ddc(dev, &connector->base, &intel_dp_connector_funcs,
> -				    type, &intel_dp->aux.ddc);
> +	intel_dp_set_source_rates(intel_dp);
> +	link_caps.nlanes = 4;
> +	link_caps.nlink_rates = intel_dp->num_source_rates;
> +	rates = kmemdup_array(intel_dp->source_rates, intel_dp->num_source_rates,
> +			      sizeof(*rates), GFP_KERNEL);
> +	if (!rates)
> +		goto fail;
> +
> +	link_caps.link_rates = rates;
> +	link_caps.dsc = HAS_DSC(display);
> +
> +	drm_connector_dp_init_with_ddc(dev, &connector->base, &intel_dp_connector_funcs,
> +				       &link_caps, type, &intel_dp->aux.ddc);
> +	kfree(rates);
> +

All of the above feels a bit clumsy in the middle of an already too long
function.

>  	drm_connector_helper_add(&connector->base, &intel_dp_connector_helper_funcs);
>  
>  	if (!HAS_GMCH(display) && DISPLAY_VER(display) < 12)
> @@ -7315,7 +7334,6 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
>  		goto fail;
>  	}
>  
> -	intel_dp_set_source_rates(intel_dp);
>  	intel_dp_set_common_rates(intel_dp);
>  	intel_dp_reset_link_params(intel_dp);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> index a26094223f780..25e0e957fe36d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> @@ -1231,6 +1231,18 @@ intel_dp_128b132b_intra_hop(struct intel_dp *intel_dp,
>  	return sink_status & DP_INTRA_HOP_AUX_REPLY_INDICATION ? 1 : 0;
>  }
>  
> +static void intel_dp_report_link_train(struct intel_dp *intel_dp)
> +{
> +	struct intel_connector *connector = intel_dp->attached_connector;
> +
> +	drm_dp_set_max_link_params(&connector->base, intel_dp->link_rate,
> +				   intel_dp->lane_count);
> +
> +	drm_dp_set_cur_link_params(&connector->base, intel_dp->link_rate,
> +				   intel_dp->lane_count,
> +				   connector->dp.dsc_decompression_enabled);
> +}
> +
>  /**
>   * intel_dp_stop_link_train - stop link training
>   * @intel_dp: DP struct
> @@ -1259,6 +1271,9 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp,
>  	intel_dp_program_link_training_pattern(intel_dp, crtc_state, DP_PHY_DPRX,
>  					       DP_TRAINING_PATTERN_DISABLE);
>  
> +	if (!intel_dp->is_mst)
> +		intel_dp_report_link_train(intel_dp);
> +
>  	if (intel_dp_is_uhbr(crtc_state)) {
>  		ret = poll_timeout_us(ret = intel_dp_128b132b_intra_hop(intel_dp, crtc_state),
>  				      ret == 0,
> @@ -1772,6 +1787,8 @@ void intel_dp_start_link_train(struct intel_atomic_state *state,
>  	 */
>  	int lttpr_count;
>  
> +	drm_dp_sink_set_link_caps(&intel_dp->attached_connector->base, &intel_dp->aux);

This is not okay.

We've already figured out all the information needed, and this call goes
ahead and reads the same information out again.

Moreover, some sinks are fragile when it comes to reading the info and
starting link training. The CTS might complain about redundant reads as
well.

drm_dp_sink_set_link_caps() as a name implies something about link,
i.e. the thing between the source and the sink. But this only sets sink
capabilities. Which also means it should not happen at link training
time at all. We figure the information out at detect, which means it's
available *before* modeset.

The more I think about the function, the more I question it. Like, if
the source doesn't support UHBR at all, or not on this connector, what's
the point of reading the sink UHBR rates?

> +
>  	intel_hpd_block(encoder);
>  
>  	lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp);

-- 
Jani Nikula, Intel


^ permalink raw reply

* Re: [PATCH v9 3/9] regulator: dt-bindings: Add MediaTek MT6392 PMIC
From: Krzysztof Kozlowski @ 2026-06-22  7:23 UTC (permalink / raw)
  To: Luca Leonardo Scorcia
  Cc: linux-mediatek, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sen Chu, Sean Wang, Macpaul Lin, Lee Jones,
	Matthias Brugger, AngeloGioacchino Del Regno, Liam Girdwood,
	Mark Brown, Linus Walleij, Julien Massot, Louis-Alexis Eyraud,
	Val Packett, Fabien Parent, Akari Tsuyukusa, Chen Zhong,
	linux-input, devicetree, linux-kernel, linux-pm, linux-arm-kernel,
	linux-gpio
In-Reply-To: <20260621081634.467858-4-l.scorcia@gmail.com>

On Sun, Jun 21, 2026 at 10:13:28AM +0200, Luca Leonardo Scorcia wrote:
> Add bindings for the regulators found in the MediaTek MT6392 PMIC,
> usually found in board designs using the MediaTek MT8516/MT8167 SoCs.
> 
> Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
> ---
>  .../regulator/mediatek,mt6392-regulator.yaml  | 112 ++++++++++++++++++
>  .../regulator/mediatek,mt6392-regulator.h     |  23 ++++
>  2 files changed, 135 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/mediatek,mt6392-regulator.yaml
>  create mode 100644 include/dt-bindings/regulator/mediatek,mt6392-regulator.h

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof



^ permalink raw reply

* [RESEND PATCH v3] coresight: etm-perf: Fix reference count leak in etm_setup_aux
From: Ma Ke @ 2026-06-22  7:10 UTC (permalink / raw)
  To: suzuki.poulose, mike.leach, james.clark, leo.yan,
	alexander.shishkin, mathieu.poirier
  Cc: coresight, linux-arm-kernel, linux-kernel, akpm, Ma Ke, stable

bus_find_device() returns a device with its reference count
incremented. When a user-selected sink is obtained through
coresight_get_sink_by_id(), etm_setup_aux() keeps using the returned
sink while building the path and allocating the sink buffer.

Therefore the lookup reference must remain valid while etm_setup_aux()
is still using the sink, otherwise the sink could be removed under the
caller. Drop the lookup reference on the common exit path, after
etm_setup_aux() no longer directly uses the user-selected sink.

The CoreSight path code takes the references it needs for built paths,
so the initial lookup reference from coresight_get_sink_by_id() is no
longer needed after setup_aux finishes.

Found by code review.

Signed-off-by: Ma Ke <make_ruc2021@163.com>
Cc: stable@vger.kernel.org
Fixes: 0e6c20517596 ("coresight: etm-perf: Allow an event to use different sinks")
---
Changes in v3:
- do not drop the lookup reference in coresight_get_sink_by_id(), as 
that would return a sink pointer without keeping the device reference 
while etm_setup_aux() is still using it.
- dropped the lookup reference in etm_setup_aux on the common exit path, 
as suggested by Suzuki.
- updated the commit message to describe why the reference is kept 
until etm_setup_aux() finishes using the sink.
Changes in v2:
- modified the patch as suggestions.
---
 drivers/hwtracing/coresight/coresight-etm-perf.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index f85dedf89a3f..d5116177c1b9 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -456,6 +456,11 @@ static void *etm_setup_aux(struct perf_event *event, void **pages,
 		goto err;
 
 out:
+	if (user_sink) {
+		put_device(&user_sink->dev);
+		user_sink = NULL;
+	}
+
 	return event_data;
 
 err:
-- 
2.43.0



^ permalink raw reply related

* Re: [PATCH] irqchip/gic-v3-its: Add Altera Agilex5 DMA workaround
From: Marc Zyngier @ 2026-06-22  7:08 UTC (permalink / raw)
  To: muhammad.nazim.amirul.nazle.asmade
  Cc: tglx, catalin.marinas, will, heiko, linux-arm-kernel,
	linux-kernel, linux-rockchip, adrian.ho.yin.ng
In-Reply-To: <20260622024945.21354-1-muhammad.nazim.amirul.nazle.asmade@altera.com>

On Mon, 22 Jun 2026 03:49:45 +0100,
muhammad.nazim.amirul.nazle.asmade@altera.com wrote:
> 
> From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
> 
> Altera Agilex5 GIC600 integration has DDR addressing limitation where
> only the first 40 bits of physical address can be accessible. Extend
> existing dma32 quirk in driver to support Agilex5.
> 
> Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
> Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>

I like the fact that you waited another *year*[1] to post a fixed
version of this change, and couldn't even be bothered to tag this as a
new version, not to mention the lack of Suggested-by: tag for code
that was provided for your perusal.

So you're late to the party, and someone else is doing actual work [2].

Please synchronise with them.

	M.

[1] https://lore.kernel.org/linux-arm-kernel/6a44509ca0edaabc17e59d2e27fef1c782183456.1751618484.git.adrianhoyin.ng@altera.com/
[2] https://lore.kernel.org/r/20260618220427.14325-3-marek.vasut+renesas@mailbox.org

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply

* Re: [PATCH RFC v2 1/4] drm: Introduce DisplayPort connector helpers with link training state
From: Jani Nikula @ 2026-06-22  7:05 UTC (permalink / raw)
  To: Kory Maincent, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rodrigo Vivi,
	Joonas Lahtinen, Tvrtko Ursulin, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Luca Ceresoli, Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
	AngeloGioacchino Del Regno, Dmitry Baryshkov, Daniel Stone
  Cc: Thomas Petazzoni, Mark Yacoub, Sean Paul, Manasi Navare,
	Drew Davenport, Louis Chauvet, Luca Ceresoli, dri-devel,
	linux-kernel, intel-gfx, intel-xe, linux-mediatek,
	linux-arm-kernel, Kory Maincent
In-Reply-To: <20260619-feat_link_cap-v2-1-a3dec4c02ad9@bootlin.com>

On Fri, 19 Jun 2026, Kory Maincent <kory.maincent@bootlin.com> wrote:
> Add managed and unmanaged DisplayPort connector initialization helpers,
> drmm_connector_dp_init() and drm_connector_dp_init_with_ddc(), modeled
> after the existing HDMI counterpart drmm_connector_hdmi_init().
>
> These helpers initialize DP-specific connector state and expose link
> training capabilities and state to userspace via sysfs attributes under
> dp_link:
>
>   - source_link_rates_caps: Array of source-supported link rates
>   - source_max_lane_count_caps: Source maximum lane count capability
>   - source_dsc_caps: Source Display Stream Compression support
>   - sink_max_link_rate_caps: Sink maximum link rate capability
>   - sink_max_lane_count_caps: Sink maximum lane count capability
>   - sink_dsc_caps: Sink DSC support
>   - cur_link_rate: Current negotiated link rate
>   - cur_lane_count: Current negotiated lane count
>   - dsc_en: DSC enabled in current link training
>   - max_link_rate: Maximum achievable link rate (limited by source/sink)
>   - max_lane_count: Maximum achievable lane count (limited by source/sink)
>
> Link rates are passed by the driver in deca-kbps, following the DRM
> convention, but exposed to userspace in kbps for clarity.
>
> Additional helpers are provided to manage link capabilities and parameters
> at runtime:
>   - drm_dp_sink_set_link_caps(): Set sink capabilities after DPCD read
>   - drm_dp_sink_reset_link_caps(): Reset sink capabilities on disconnect
>   - drm_dp_set_cur_link_params(): Update current link training parameters
>   - drm_dp_set_max_link_params(): Update maximum achievable parameters
>
> The aim of such development is to guide users to select the most suitable
> DisplayPort connector for their needs. For example, if you have a USB-C
> hub with lesser capabilities than your computer’s native DisplayPort
> connector (such as HBR2 versus HBR3 support), the system could recommend
> connecting high-resolution displays directly to the computer’s port
> instead of through the hub to ensure optimal performance.
>
> Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
> ---
>
> Changes in v2:
> - Remove voltage swing and pre-emphasis properties
> - Expose link training state via sysfs dp_link/ group instead of
>   connector properties
> - Rename variables from link_train to link as they relate directly to
>   the link capabilities
> - Add comprehensive sysfs attributes for both source and sink capabilities
> - Add separate helpers for managing sink capabilities and for current and
>   maximum link parameters
> ---
>  drivers/gpu/drm/display/drm_dp_helper.c | 144 ++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_connector.c         | 122 +++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_sysfs.c             | 100 ++++++++++++++++++++++
>  include/drm/display/drm_dp_helper.h     |   7 ++
>  include/drm/drm_connector.h             | 105 +++++++++++++++++++++++
>  5 files changed, 478 insertions(+)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
> index 9c31e14cc413b..bd0e1eb657412 100644
> --- a/drivers/gpu/drm/display/drm_dp_helper.c
> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> @@ -4900,3 +4900,147 @@ int drm_dp_max_dprx_data_rate(int max_link_rate, int max_lanes)
>  				  1000000 * 8);
>  }
>  EXPORT_SYMBOL(drm_dp_max_dprx_data_rate);
> +
> +static int drm_dp_dpcd_read_link_rate_caps(struct drm_dp_aux *aux)
> +{
> +	u8 data;
> +	int ret;
> +
> +	ret = drm_dp_dpcd_read_byte(aux, DP_DP13_DPCD_REV + DP_MAIN_LINK_CHANNEL_CODING, &data);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (data & DP_CAP_ANSI_128B132B) {
> +		ret = drm_dp_dpcd_read_byte(aux, DP_128B132B_SUPPORTED_LINK_RATES, &data);
> +		if (ret < 0)
> +			return ret;
> +
> +		if (data & DP_UHBR20)
> +			return 20000000;
> +		if (data & DP_UHBR13_5)
> +			return 13500000;
> +		if (data & DP_UHBR10)
> +			return 10000000;
> +	}
> +
> +	ret = drm_dp_dpcd_read_byte(aux, DP_MAX_LINK_RATE, &data);
> +	if (ret < 0)
> +		return ret;
> +
> +	return data * 270000;
> +}

There are three ways of reporting the sink link rates. DP_MAX_LINK_RATE
is the only one that reports the maximum. The other two can report any
rates. The above doesn't handle DP_SUPPORTED_LINK_RATES.

The drivers need to figure out *all* supported rates. What is the point
of adding a "helper" that reads these DPCD registers but only reports
the max rate? Using this will only mean duplicated reads of the
registers. This may confuse the sinks, as well as the CTS.

This is not a good design.

> +
> +/**
> + * drm_dp_sink_set_link_caps - Set DisplayPort sink link capabilities
> + * @connector: DisplayPort connector
> + * @aux: The DP AUX channel to use
> + *
> + * This function sets the DisplayPort sink (monitor) link training capabilities
> + * for the given connector. These capabilities are typically read from the
> + * sink's DPCD registers during HPD processing.
> + */
> +void drm_dp_sink_set_link_caps(struct drm_connector *connector,
> +			       struct drm_dp_aux *aux)
> +{
> +	u32 lane_count, link_rate;
> +	u8 data;
> +	int ret;
> +
> +	if (!connector)
> +		return;
> +
> +	WARN_ON(!drm_modeset_is_locked(&connector->dev->mode_config.connection_mutex));
> +
> +	ret = drm_dp_dpcd_read_byte(aux, DP_MAX_LANE_COUNT, &data);
> +	if (ret < 0)
> +		return;
> +
> +	lane_count = data & DP_MAX_LANE_COUNT_MASK;
> +
> +	ret = drm_dp_dpcd_read_link_rate_caps(aux);
> +	if (ret < 0)
> +		return;
> +
> +	link_rate = ret;
> +
> +	ret = drm_dp_dpcd_read_byte(aux, DP_DSC_SUPPORT, &data);
> +	if (ret < 0)
> +		return;
> +
> +	connector->dp.sink_max_lane_count_caps = lane_count;
> +	connector->dp.sink_max_link_rate_caps = link_rate;
> +	connector->dp.sink_dsc_caps = ret & DP_DSC_DECOMPRESSION_IS_SUPPORTED;
> +}
> +EXPORT_SYMBOL_GPL(drm_dp_sink_set_link_caps);
> +
> +/**
> + * drm_dp_set_cur_link_params - Set current DisplayPort link parameters
> + * @connector: DisplayPort connector
> + * @link_rate: Current link rate in deca-kbps
> + * @lane_count: Current lane count
> + * @dsc_en: Display Stream Compression enabled
> + *
> + * This function sets the current active DisplayPort link parameters after
> + * link training has completed. These parameters represent the actual link
> + * configuration being used for display output.
> + */
> +void drm_dp_set_cur_link_params(struct drm_connector *connector,
> +				u32 link_rate, u32 lane_count, bool dsc_en)
> +{
> +	if (!connector)
> +		return;
> +
> +	WARN_ON(!drm_modeset_is_locked(&connector->dev->mode_config.connection_mutex));
> +
> +	/* Convert deca-kbps in kbps */
> +	connector->dp.cur_link_rate = link_rate * 10;
> +	connector->dp.cur_lane_count = lane_count;
> +	connector->dp.dsc_en = dsc_en;
> +}
> +EXPORT_SYMBOL_GPL(drm_dp_set_cur_link_params);
> +
> +/**
> + * drm_dp_set_max_link_params - Set maximum DisplayPort link parameters
> + * @connector: DisplayPort connector
> + * @link_rate: Maximum link rate in kbps
> + * @lane_count: Maximum lane count
> + *
> + * This function sets the maximum achievable DisplayPort link parameters,
> + * which represent the intersection of source and sink capabilities. These
> + * values are the upper bounds for link training attempts.
> + */
> +void drm_dp_set_max_link_params(struct drm_connector *connector, u32 link_rate,
> +				u32 lane_count)
> +{
> +	if (!connector)
> +		return;
> +
> +	WARN_ON(!drm_modeset_is_locked(&connector->dev->mode_config.connection_mutex));
> +
> +	connector->dp.max_link_rate = link_rate;
> +	connector->dp.max_lane_count = lane_count;
> +}
> +EXPORT_SYMBOL_GPL(drm_dp_set_max_link_params);
> +
> +/**
> + * drm_dp_sink_reset_link_caps - Reset DisplayPort sink capabilities
> + * @connector: DisplayPort connector
> + *
> + * This function resets all DisplayPort sink link capabilities and parameters
> + * to their default state. This should be called when a sink is disconnected
> + * to clear stale capability information.
> + */
> +void drm_dp_sink_reset_link_caps(struct drm_connector *connector)
> +{
> +	if (!connector)
> +		return;
> +
> +	WARN_ON(!drm_modeset_is_locked(&connector->dev->mode_config.connection_mutex));
> +
> +	drm_dp_set_cur_link_params(connector, 0, 0, false);
> +	drm_dp_set_max_link_params(connector, 0, 0);
> +	connector->dp.sink_max_link_rate_caps = 0;
> +	connector->dp.sink_max_lane_count_caps = 0;
> +	connector->dp.sink_dsc_caps = false;
> +}
> +EXPORT_SYMBOL_GPL(drm_dp_sink_reset_link_caps);
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index a5d13b92b665c..259af3240c057 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -489,6 +489,128 @@ int drm_connector_init_with_ddc(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(drm_connector_init_with_ddc);
>  
> +static int drm_dp_source_set_link_caps(struct drm_connector *connector,
> +				       const struct drm_connector_dp_link_caps *link_caps)
> +{
> +	u32 *_link_rates;
> +
> +	_link_rates = devm_kmemdup_array(connector->dev->dev,
> +					 link_caps->link_rates,
> +					 link_caps->nlink_rates,
> +					 sizeof(*link_caps->link_rates),
> +					 GFP_KERNEL);
> +	if (!_link_rates)
> +		return -ENOMEM;
> +
> +	for (int i = 0; i < link_caps->nlink_rates; i++)
> +		/* Convert deca-kbps in kbps */
> +		_link_rates[i] *= 10;

Why do you have different rates in different places? Ditch the
conversions?

> +
> +	connector->dp.source_link_rates_caps = _link_rates;
> +	connector->dp.source_num_link_rates_caps = link_caps->nlink_rates;
> +	connector->dp.source_max_lane_count_caps = link_caps->nlanes;
> +	connector->dp.source_dsc_caps = link_caps->dsc;

Why do you define a struct, and then not use it as a sub-struct in
connector->dp?

> +
> +	return 0;
> +}
> +
> +/**
> + * drmm_connector_dp_init - Init a preallocated DisplayPort connector
> + * @dev: DRM device
> + * @connector: A pointer to the DisplayPort connector to init
> + * @funcs: callbacks for this connector
> + * @dp_link_caps: DisplayPort link training capabilities. The pointer
> + *		  is not kept by the DRM core
> + * @connector_type: user visible type of the connector
> + * @ddc: optional pointer to the associated ddc adapter
> + *
> + * Initialises a preallocated DisplayPort connector. Connectors can be
> + * subclassed as part of driver connector objects.
> + *
> + * Cleanup is automatically handled with a call to
> + * drm_connector_cleanup() in a DRM-managed action.
> + *
> + * The connector structure should be allocated with drmm_kzalloc().
> + *
> + * The @drm_connector_funcs.destroy hook must be NULL.
> + *
> + * Returns:
> + * Zero on success, error code on failure.
> + */
> +int drmm_connector_dp_init(struct drm_device *dev,
> +			   struct drm_connector *connector,
> +			   const struct drm_connector_funcs *funcs,
> +			   const struct drm_connector_dp_link_caps *dp_link_caps,
> +			   int connector_type,
> +			   struct i2c_adapter *ddc)
> +{
> +	int ret;
> +
> +	if (!(connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
> +	      connector_type == DRM_MODE_CONNECTOR_eDP))
> +		return -EINVAL;
> +
> +	if (!dp_link_caps)
> +		return -EINVAL;
> +
> +	ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc);
> +	if (ret)
> +		return ret;
> +
> +	return drm_dp_source_set_link_caps(connector, dp_link_caps);
> +}
> +EXPORT_SYMBOL(drmm_connector_dp_init);
> +
> +/**
> + * drm_connector_dp_init_with_ddc - Init a preallocated DisplayPort connector
> + * @dev: DRM device
> + * @connector: A pointer to the DisplayPort connector to init
> + * @funcs: callbacks for this connector
> + * @dp_link_caps: DisplayPort link training capabilities. The pointer
> + *		  is not kept by the DRM core
> + * @connector_type: user visible type of the connector
> + * @ddc: optional pointer to the associated ddc adapter
> + *
> + * Initialises a preallocated connector. Connectors should be
> + * subclassed as part of driver connector objects.
> + *
> + * At driver unload time the driver's &drm_connector_funcs.destroy hook
> + * should call drm_connector_cleanup() and free the connector structure.
> + * The connector structure should not be allocated with devm_kzalloc().
> + *
> + * Ensures that the ddc field of the connector is correctly set.
> + *
> + * Note: consider using drmm_connector_dp_init() instead of
> + * drm_connector_dp_init_with_ddc() to let the DRM managed resource
> + * infrastructure take care of cleanup and deallocation.
> + *
> + * Returns:
> + * Zero on success, error code on failure.
> + */
> +int drm_connector_dp_init_with_ddc(struct drm_device *dev,
> +				   struct drm_connector *connector,
> +				   const struct drm_connector_funcs *funcs,
> +				   const struct drm_connector_dp_link_caps *dp_link_caps,
> +				   int connector_type,
> +				   struct i2c_adapter *ddc)
> +{
> +	int ret;
> +
> +	if (!(connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
> +	      connector_type == DRM_MODE_CONNECTOR_eDP))
> +		return -EINVAL;
> +
> +	if (!dp_link_caps)
> +		return -EINVAL;
> +
> +	ret = drm_connector_init_with_ddc(dev, connector, funcs, connector_type, ddc);
> +	if (ret)
> +		return ret;
> +
> +	return drm_dp_source_set_link_caps(connector, dp_link_caps);
> +}
> +EXPORT_SYMBOL(drm_connector_dp_init_with_ddc);
> +
>  static void drm_connector_cleanup_action(struct drm_device *dev,
>  					 void *ptr)
>  {
> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> index ef4e923a87284..653fecf23d717 100644
> --- a/drivers/gpu/drm/drm_sysfs.c
> +++ b/drivers/gpu/drm/drm_sysfs.c
> @@ -340,6 +340,95 @@ static const struct attribute_group *connector_dev_groups[] = {
>  	NULL
>  };
>  
> +static ssize_t drm_link_rates_show(u32 num_link_rates, const u32 *link_rates, char *buf)
> +{
> +	int size = 0;
> +
> +	if (!num_link_rates)
> +		return 0;
> +
> +	size += sysfs_emit_at(buf, size, "%d", link_rates[0]);
> +	for (int i = 1; i < num_link_rates; i++)
> +		size += sysfs_emit_at(buf, size, " %d", link_rates[i]);
> +
> +	size += sysfs_emit_at(buf, size, "\n");
> +	return size;
> +}
> +
> +static ssize_t source_link_rates_caps_show(struct device *device,
> +					   struct device_attribute *attr,
> +					   char *buf)
> +{
> +	struct drm_connector *connector = to_drm_connector(device);
> +	ssize_t size;
> +
> +	drm_modeset_lock(&connector->dev->mode_config.connection_mutex, NULL);
> +	size = drm_link_rates_show(connector->dp.source_num_link_rates_caps,
> +				   connector->dp.source_link_rates_caps, buf);
> +	drm_modeset_unlock(&connector->dev->mode_config.connection_mutex);
> +	return size;
> +}
> +
> +#define DRM_CONNECTOR_DP_ATTR_SHOW_SIMPLE(_name) \
> +static ssize_t _name##_show(struct device *device, \
> +			    struct device_attribute *attr, \
> +			    char *buf) \
> +{ \
> +	struct drm_connector *connector = to_drm_connector(device); \
> +	int ret; \
> +	drm_modeset_lock(&connector->dev->mode_config.connection_mutex, NULL); \
> +	if (!connector->dp._name) { \
> +		drm_modeset_unlock(&connector->dev->mode_config.connection_mutex); \
> +		return 0; \
> +	} \
> +	ret = sysfs_emit(buf, "%d\n", connector->dp._name); \
> +	drm_modeset_unlock(&connector->dev->mode_config.connection_mutex); \
> +	return ret; \
> +}
> +
> +DRM_CONNECTOR_DP_ATTR_SHOW_SIMPLE(source_max_lane_count_caps);
> +DRM_CONNECTOR_DP_ATTR_SHOW_SIMPLE(source_dsc_caps);
> +DRM_CONNECTOR_DP_ATTR_SHOW_SIMPLE(sink_dsc_caps);
> +DRM_CONNECTOR_DP_ATTR_SHOW_SIMPLE(sink_max_link_rate_caps);
> +DRM_CONNECTOR_DP_ATTR_SHOW_SIMPLE(sink_max_lane_count_caps);
> +DRM_CONNECTOR_DP_ATTR_SHOW_SIMPLE(cur_link_rate);
> +DRM_CONNECTOR_DP_ATTR_SHOW_SIMPLE(cur_lane_count);
> +DRM_CONNECTOR_DP_ATTR_SHOW_SIMPLE(dsc_en);
> +DRM_CONNECTOR_DP_ATTR_SHOW_SIMPLE(max_link_rate);
> +DRM_CONNECTOR_DP_ATTR_SHOW_SIMPLE(max_lane_count);
> +
> +static DEVICE_ATTR_RO(source_link_rates_caps);
> +static DEVICE_ATTR_RO(source_max_lane_count_caps);
> +static DEVICE_ATTR_RO(source_dsc_caps);
> +static DEVICE_ATTR_RO(sink_max_link_rate_caps);
> +static DEVICE_ATTR_RO(sink_max_lane_count_caps);
> +static DEVICE_ATTR_RO(sink_dsc_caps);
> +static DEVICE_ATTR_RO(cur_link_rate);
> +static DEVICE_ATTR_RO(cur_lane_count);
> +static DEVICE_ATTR_RO(dsc_en);
> +static DEVICE_ATTR_RO(max_link_rate);
> +static DEVICE_ATTR_RO(max_lane_count);
> +
> +static struct attribute *connector_dp_link_attrs[] = {
> +	&dev_attr_source_link_rates_caps.attr,
> +	&dev_attr_source_max_lane_count_caps.attr,
> +	&dev_attr_source_dsc_caps.attr,
> +	&dev_attr_sink_max_link_rate_caps.attr,
> +	&dev_attr_sink_max_lane_count_caps.attr,
> +	&dev_attr_sink_dsc_caps.attr,
> +	&dev_attr_cur_link_rate.attr,
> +	&dev_attr_cur_lane_count.attr,
> +	&dev_attr_dsc_en.attr,
> +	&dev_attr_max_link_rate.attr,
> +	&dev_attr_max_lane_count.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group connector_dp_link_group = {
> +	.name = "dp_link",
> +	.attrs = connector_dp_link_attrs,
> +};
> +
>  int drm_sysfs_connector_add(struct drm_connector *connector)
>  {
>  	struct drm_device *dev = connector->dev;
> @@ -376,6 +465,15 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
>  
>  	connector->kdev = kdev;
>  
> +	if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
> +	    connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
> +		r = sysfs_create_group(&connector->kdev->kobj, &connector_dp_link_group);
> +		if (r) {
> +			drm_err(dev, "failed to create DP connector sysfs: %d\n", r);
> +			goto err_dp_sysfs;
> +		}
> +	}
> +
>  	if (dev_fwnode(kdev)) {
>  		r = component_add(kdev, &typec_connector_ops);
>  		if (r)
> @@ -384,6 +482,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
>  
>  	return 0;
>  
> +err_dp_sysfs:
> +	device_del(kdev);
>  err_free:
>  	put_device(kdev);
>  	return r;
> diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
> index 8c2d77a032f06..e7620ecb2380a 100644
> --- a/include/drm/display/drm_dp_helper.h
> +++ b/include/drm/display/drm_dp_helper.h
> @@ -1031,4 +1031,11 @@ ssize_t drm_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, struct dp_sdp *sdp
>  int drm_dp_link_symbol_cycles(int lane_count, int pixels, int dsc_slice_count,
>  			      int bpp_x16, int symbol_size, bool is_mst);
>  
> +void drm_dp_sink_set_link_caps(struct drm_connector *connector, struct drm_dp_aux *aux);
> +void drm_dp_sink_reset_link_caps(struct drm_connector *connector);
> +void drm_dp_set_cur_link_params(struct drm_connector *connector, u32 link_rate,
> +				u32 lane_count, bool dsc_en);
> +void drm_dp_set_max_link_params(struct drm_connector *connector, u32 link_rate,
> +				u32 lane_count);
> +
>  #endif /* _DRM_DP_HELPER_H_ */
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 529755c2e8620..a08b8e9766abe 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -2003,6 +2003,93 @@ struct drm_connector_cec {
>  	void *data;
>  };
>  
> +/**
> + * struct drm_connector_dp_link_caps - DRM DisplayPort link capabilities
> + */
> +struct drm_connector_dp_link_caps {
> +	/**
> +	 * @nlanes: Maximum number of lanes number supported
> +	 */
> +	u8 nlanes;
> +
> +	/**
> +	 * @nlink_rates: Number of link rates supported
> +	 */
> +	u32 nlink_rates;
> +
> +	/**
> +	 * @link_rates: Array listing the supported link rates in deca-kbps
> +	 */
> +	const u32 *link_rates;

Just make all of the above ints? There's nothing specifically u32 or u8
about any of them. They're just integers.

> +
> +	/**
> +	 * @dsc: Display Stream Compression supported
> +	 */
> +	bool dsc;
> +};
> +
> +/**
> + * struct drm_connector_dp - DRM Connector DisplayPort-related structure
> + */
> +struct drm_connector_dp {
> +	/**
> +	 * @source_link_rates_caps: Array of supported link rates by the
> +	 * source in kbps
> +	 */
> +	const u32 *source_link_rates_caps;
> +	/**
> +	 * @source_num_link_rates_caps: Number of link rates in
> +	 * @source_link_rates_caps array
> +	 */
> +	u32 source_num_link_rates_caps;
> +	/**
> +	 * @source_max_lane_count_caps: Maximum number of lanes supported by
> +	 * the source
> +	 */
> +	u32 source_max_lane_count_caps;
> +	/**
> +	 * @source_dsc_caps: Display Stream Compression capability of the
> +	 * source
> +	 */
> +	bool source_dsc_caps;

Why doesn't the above use a struct?

> +	/**
> +	 * @sink_max_link_rate_caps: Maximum link rate supported by the sink
> +	 * in kbps
> +	 */
> +	u32 sink_max_link_rate_caps;

Why all rates for source, but just one rate for sink? Why is it called
_caps?


> +	/**
> +	 * @sink_max_lane_count_caps: Maximum number of lanes supported by the
> +	 * sink
> +	 */
> +	u32 sink_max_lane_count_caps;
> +	/**
> +	 * @sink_dsc_caps: Display Stream Compression capability of the sink
> +	 */
> +	bool sink_dsc_caps;

Could use the same struct here.

> +	/**
> +	 * @cur_link_rate: Current negotiated link rate in kbps
> +	 */
> +	u32 cur_link_rate;
> +	/**
> +	 * @cur_lane_count: Current negotiated number of lanes
> +	 */
> +	u32 cur_lane_count;
> +	/**
> +	 * @dsc_en: Display Stream Compression enabled status
> +	 */

These should be ints.

> +	bool dsc_en;
> +	/**
> +	 * @max_link_rate: Maximum achievable link rate considering both
> +	 * source and sink capabilities in deca-kbps
> +	 */
> +	u32 max_link_rate;

IMO this should be an intersection of source and sink rates.

> +	/**
> +	 * @max_lane_count: Maximum achievable lane count considering both
> +	 * source and sink capabilities
> +	 */
> +	u32 max_lane_count;

These should be ints.

> +};
> +
>  /**
>   * struct drm_connector - central DRM connector control structure
>   *
> @@ -2426,6 +2513,11 @@ struct drm_connector {
>  	 * @cec: CEC-related data.
>  	 */
>  	struct drm_connector_cec cec;
> +
> +	/**
> +	 * @dp: DisplayPort-related variable and properties.
> +	 */
> +	struct drm_connector_dp dp;
>  };
>  
>  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
> @@ -2458,6 +2550,19 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
>  			     struct i2c_adapter *ddc,
>  			     unsigned long supported_formats,
>  			     unsigned int max_bpc);
> +int drm_connector_dp_init_with_ddc(struct drm_device *dev,
> +				   struct drm_connector *connector,
> +				   const struct drm_connector_funcs *funcs,
> +				   const struct drm_connector_dp_link_caps *dp_link_caps,
> +				   int connector_type,
> +				   struct i2c_adapter *ddc);
> +
> +int drmm_connector_dp_init(struct drm_device *dev,
> +			   struct drm_connector *connector,
> +			   const struct drm_connector_funcs *funcs,
> +			   const struct drm_connector_dp_link_caps *dp_link_caps,
> +			   int connector_type,
> +			   struct i2c_adapter *ddc);
>  void drm_connector_attach_edid_property(struct drm_connector *connector);
>  int drm_connector_register(struct drm_connector *connector);
>  int drm_connector_dynamic_register(struct drm_connector *connector);

-- 
Jani Nikula, Intel


^ permalink raw reply

* Re: [PATCH v2 3/4] irqchip/gic-v3: Add Renesas R-Car Gen4 erratum workaround
From: Marc Zyngier @ 2026-06-22  6:55 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Thomas Gleixner, linux-pci, Yoshihiro Shimoda,
	Krzysztof Wilczyński, Bjorn Helgaas, Catalin Marinas,
	Conor Dooley, Geert Uytterhoeven, Krzysztof Kozlowski,
	Lorenzo Pieralisi, Manivannan Sadhasivam, Rob Herring, devicetree,
	linux-arm-kernel, linux-doc, linux-kernel, linux-renesas-soc
In-Reply-To: <d6fce333-4353-4e49-873f-eb3187a631e4@mailbox.org>

On Sun, 21 Jun 2026 23:46:25 +0100,
Marek Vasut <marek.vasut@mailbox.org> wrote:
> 
> On 6/21/26 12:59 PM, Thomas Gleixner wrote:
> > On Fri, Jun 19 2026 at 00:02, Marek Vasut wrote:
> >> Renesas R-Car S4/V4H/V4M GIC600 integration has address width for AXI
> >> or APB interface configured to 32 bit, it can therefore access only
> >> the first 4 GiB of physical address space. This information comes from
> >> R-Car V4H Interface Specification sheet, there is currently no technical
> >> update number assigned to this limitation. Further input from hardware
> >> engineer indicates that this limitation also applies to R-Car S4 and V4M.
> >> Name the limitation GEN4GICITS1, and add a driver quirk to mitigate this
> >> limitation.
> >> 
> >> The quirk is keyed on the combination of the GIC implementation
> >> and the platform identification in the device tree.
> >> 
> >> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> >> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
> > 
> > This SOB chain is broken.
> 
> Broken ? I don't understand , could you please elaborate ?

Either Shimoda-san is the sole author of the change and you are
posting their work, then the first line of the patch should say:

 From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

with your own SoB immediately following their SoB (see [1]).

Or this has been co-developed, and both of you should be credited as
authors. then Shimoda-san's SoB should be preceded by their
Co-developed-by: tag (see [2]).

 Co-developed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
 Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
 Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>

This shows exactly who did what, who forwarded whose patch, and forms
the base of the DCO which is documented at [3].

Thanks,

	M.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst#n449
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst#n503
[3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst#n396

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply

* Re: [PATCH v9 1/9] dt-bindings: mfd: mt6397: Add MT6392 PMIC
From: Krzysztof Kozlowski @ 2026-06-22  6:52 UTC (permalink / raw)
  To: Luca Leonardo Scorcia
  Cc: linux-mediatek, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sen Chu, Sean Wang, Macpaul Lin, Lee Jones,
	Matthias Brugger, AngeloGioacchino Del Regno, Liam Girdwood,
	Mark Brown, Linus Walleij, Val Packett, Louis-Alexis Eyraud,
	Julien Massot, Fabien Parent, Akari Tsuyukusa, Chen Zhong,
	linux-input, devicetree, linux-kernel, linux-pm, linux-arm-kernel,
	linux-gpio
In-Reply-To: <20260621081634.467858-2-l.scorcia@gmail.com>

On Sun, Jun 21, 2026 at 10:13:26AM +0200, Luca Leonardo Scorcia wrote:
>                - enum:
>                    - mediatek,mt6359-rtc
> @@ -99,6 +107,7 @@ properties:
>                - mediatek,mt6331-regulator
>                - mediatek,mt6358-regulator
>                - mediatek,mt6359-regulator
> +              - mediatek,mt6392-regulator
>                - mediatek,mt6397-regulator
>            - items:
>                - enum:
> @@ -663,3 +672,69 @@ examples:
>              compatible = "mediatek,mt6397-rtc";
>          };
>      };
> +
> +  - |
> +    #include <dt-bindings/input/input.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    pmic {
> +        compatible = "mediatek,mt6392", "mediatek,mt6323";

You already have three examples, that's rather close to max expected
number of them. I suggest dropping.

Anyway,

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof



^ permalink raw reply

* Re: [PATCH v10 3/4] dt-bindings: clock: imx95-blk-ctl: Define formatter child node schema
From: Krzysztof Kozlowski @ 2026-06-22  6:50 UTC (permalink / raw)
  To: guoniu.zhou
  Cc: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
	Michael Turquette, Stephen Boyd, imx, linux-media, devicetree,
	linux-arm-kernel, linux-kernel, linux-clk, Guoniu Zhou
In-Reply-To: <20260618-csi_formatter-v10-3-f23830312ba5@oss.nxp.com>

On Thu, Jun 18, 2026 at 05:41:37PM +0800, guoniu.zhou@oss.nxp.com wrote:
> From: Guoniu Zhou <guoniu.zhou@nxp.com>
> 
> The Camera CSR contains control registers for multiple CSI formatter IPs
> at different register offsets. Each formatter is an independent hardware
> block with its own clock input and media pipeline connection.
> 
> Define schema to allow formatter child nodes under nxp,imx95-camera-csr,
> with 'reg' property specifying the formatter's register offset within the
> CSR address space.
> 
> Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
> ---
> Changes in v10:
> - Use single quotes for regex pattern to be consistent (Krzysztof Kozlowski)
> - Add formatter subnode binding and camera-csr syscon example
> - Update commit title and message
> 
> Changes in v9:
> - New patch to address the issue of formatter acting as a child node of syscon
> ---
>  .../bindings/clock/nxp,imx95-blk-ctl.yaml          | 64 +++++++++++++++++++++-
>  1 file changed, 63 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> index 534fa219d9f9..b4d0a7670fac 100644
> --- a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> +++ b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> @@ -46,7 +46,27 @@ required:
>    - power-domains
>    - clocks
>  
> -additionalProperties: false
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: nxp,imx95-camera-csr
> +    then:
> +      properties:
> +        '#address-cells':
> +          const: 1
> +        '#size-cells':
> +          const: 1

These should go to top-level. In if:then:else: you only narrow them,
e.g. you disallow for other variants (": false").

if:
then:
....
  required:
   ....
else:
  properties:
    '#address-cells': false

> +      required:
> +        - '#address-cells'
> +        - '#size-cells'
> +      patternProperties:
> +        '^formatter@[0-9a-f]+$':
> +          type: object
> +          $ref: /schemas/media/fsl,imx95-csi-formatter.yaml#

This as well should be in top-level and here you only disallow it for
other variants.

You can avoid cross-tree dependencies by using compatible style:
https://elixir.bootlin.com/linux/v7.1-rc6/source/Documentation/devicetree/bindings/display/msm/qcom,sm8750-mdss.yaml#L41


Best regards,
Krzysztof



^ permalink raw reply

* Re: [PATCH v6 17/21] RISC-V: perf: Add Qemu virt machine events
From: Charlie Jenkins @ 2026-06-22  6:44 UTC (permalink / raw)
  To: Atish Patra
  Cc: James Clark, Rob Herring, Arnaldo Carvalho de Melo, Jiri Olsa,
	Will Deacon, Mark Rutland, Anup Patel, Namhyung Kim,
	Paul Walmsley, Krzysztof Kozlowski, Ian Rogers, linux-riscv,
	linux-kernel, linux-perf-users, Conor Dooley, devicetree,
	linux-arm-kernel
In-Reply-To: <20260608-counter_delegation-v6-17-285b72ed65a9@meta.com>

On Mon, Jun 08, 2026 at 11:01:31PM -0700, Atish Patra wrote:
> From: Atish Patra <atishp@rivosinc.com>
> 
> Qemu virt machine supports a very minimal set of legacy perf events.
> Add them to the vendor table so that users can use them when
> counter delegation is enabled.
> 
> Signed-off-by: Atish Patra <atishp@rivosinc.com>
> ---
>  arch/riscv/include/asm/vendorid_list.h |  4 ++++
>  drivers/perf/riscv_pmu_sbi.c           | 36 ++++++++++++++++++++++++++++++++++
>  2 files changed, 40 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h
> index 7f5030ee1fcf..603aa2b21c0b 100644
> --- a/arch/riscv/include/asm/vendorid_list.h
> +++ b/arch/riscv/include/asm/vendorid_list.h
> @@ -11,4 +11,8 @@
>  #define SIFIVE_VENDOR_ID	0x489
>  #define THEAD_VENDOR_ID		0x5b7
>  
> +#define QEMU_VIRT_VENDOR_ID		0x000
> +#define QEMU_VIRT_IMPL_ID		0x000
> +#define QEMU_VIRT_ARCH_ID		0x000

Palmer proposed a change to this a while ago to set the archid for qemu
as 42 but it looks like it was never merged in qemu, but it was merged
into the riscv spec.

Here is the spec PR: https://github.com/riscv/riscv-isa-manual/pull/1213
Here is the current spec: https://github.com/riscv/riscv-isa-manual/blob/main/marchid.md
Here is the QEMU patch: https://lore.kernel.org/all/20240131182430.20174-1-palmer@rivosinc.com/

Should we follow up with this/maybe this should be accounted for here as
an alternate id?

- Charlie

> +
>  #endif
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index 00b84b28117a..74acac54328e 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -26,6 +26,7 @@
>  #include <asm/sbi.h>
>  #include <asm/cpufeature.h>
>  #include <asm/vendor_extensions.h>
> +#include <asm/vendorid_list.h>
>  #include <asm/vendor_extensions/andes.h>
>  #include <asm/hwcap.h>
>  #include <asm/csr_ind.h>
> @@ -453,7 +454,42 @@ struct riscv_vendor_pmu_events {
>  	  .hw_event_map = _hw_event_map, .cache_event_map = _cache_event_map, \
>  	  .attrs_events = _attrs },
>  
> +/* QEMU virt PMU events */
> +static const struct riscv_pmu_event qemu_virt_hw_event_map[PERF_COUNT_HW_MAX] = {
> +	PERF_MAP_ALL_UNSUPPORTED,
> +	[PERF_COUNT_HW_CPU_CYCLES]		= {0x01, 0xFFFFFFF8},
> +	[PERF_COUNT_HW_INSTRUCTIONS]		= {0x02, 0xFFFFFFF8}
> +};
> +
> +static const struct riscv_pmu_event qemu_virt_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
> +						[PERF_COUNT_HW_CACHE_OP_MAX]
> +						[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
> +	PERF_CACHE_MAP_ALL_UNSUPPORTED,
> +	[C(DTLB)][C(OP_READ)][C(RESULT_MISS)]	= {0x10019, 0xFFFFFFF8},
> +	[C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)]	= {0x1001B, 0xFFFFFFF8},
> +
> +	[C(ITLB)][C(OP_READ)][C(RESULT_MISS)]	= {0x10021, 0xFFFFFFF8},
> +};
> +
> +RVPMU_EVENT_CMASK_ATTR(cycles, cycles, 0x01, 0xFFFFFFF8);
> +RVPMU_EVENT_CMASK_ATTR(instructions, instructions, 0x02, 0xFFFFFFF8);
> +RVPMU_EVENT_CMASK_ATTR(dTLB-load-misses, dTLB_load_miss, 0x10019, 0xFFFFFFF8);
> +RVPMU_EVENT_CMASK_ATTR(dTLB-store-misses, dTLB_store_miss, 0x1001B, 0xFFFFFFF8);
> +RVPMU_EVENT_CMASK_ATTR(iTLB-load-misses, iTLB_load_miss, 0x10021, 0xFFFFFFF8);
> +
> +static struct attribute *qemu_virt_event_group[] = {
> +	RVPMU_EVENT_ATTR_PTR(cycles),
> +	RVPMU_EVENT_ATTR_PTR(instructions),
> +	RVPMU_EVENT_ATTR_PTR(dTLB_load_miss),
> +	RVPMU_EVENT_ATTR_PTR(dTLB_store_miss),
> +	RVPMU_EVENT_ATTR_PTR(iTLB_load_miss),
> +	NULL,
> +};
> +
>  static struct riscv_vendor_pmu_events pmu_vendor_events_table[] = {
> +	RISCV_VENDOR_PMU_EVENTS(QEMU_VIRT_VENDOR_ID, QEMU_VIRT_ARCH_ID, QEMU_VIRT_IMPL_ID,
> +				qemu_virt_hw_event_map, qemu_virt_cache_event_map,
> +				qemu_virt_event_group)
>  };
>  
>  static const struct riscv_pmu_event *current_pmu_hw_event_map;
> 
> -- 
> 2.53.0-Meta
> 
> 


^ permalink raw reply

* Re: [PATCH v10 2/4] media: dt-bindings: Add CSI Pixel Formatter DT bindings
From: Krzysztof Kozlowski @ 2026-06-22  6:44 UTC (permalink / raw)
  To: guoniu.zhou
  Cc: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
	Michael Turquette, Stephen Boyd, imx, linux-media, devicetree,
	linux-arm-kernel, linux-kernel, linux-clk, Guoniu Zhou
In-Reply-To: <20260618-csi_formatter-v10-2-f23830312ba5@oss.nxp.com>

On Thu, Jun 18, 2026 at 05:41:36PM +0800, guoniu.zhou@oss.nxp.com wrote:
> From: Guoniu Zhou <guoniu.zhou@nxp.com>
> 
> The i.MX95 CSI pixel formatting module uses packet info, pixel and
> non-pixel data from the CSI-2 host controller and reformat them to
> match Pixel Link(PL) definition.
> 
> Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
> ---
> Changes in v10:

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof



^ permalink raw reply

* Re: [PATCH v6 07/21] RISC-V: Add Sscfg extension CSR definition
From: Charlie Jenkins @ 2026-06-22  6:43 UTC (permalink / raw)
  To: Atish Patra
  Cc: James Clark, Rob Herring, Arnaldo Carvalho de Melo, Jiri Olsa,
	Will Deacon, Mark Rutland, Anup Patel, Namhyung Kim,
	Paul Walmsley, Krzysztof Kozlowski, Ian Rogers, linux-riscv,
	linux-kernel, linux-perf-users, Conor Dooley, devicetree,
	linux-arm-kernel
In-Reply-To: <20260608-counter_delegation-v6-7-285b72ed65a9@meta.com>

On Mon, Jun 08, 2026 at 11:01:21PM -0700, Atish Patra wrote:
> From: Kaiwen Xue <kaiwenx@rivosinc.com>
> 
> This adds the scountinhibit CSR definition and S-mode accessible hpmevent
> bits defined by smcdeleg/ssccfg. scountinhibit allows S-mode to start/stop
> counters directly from S-mode without invoking SBI calls to M-mode. It is
> also used to figure out the counters delegated to S-mode by the M-mode as
> well.
> 
> Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
> Reviewed-by: Clément Léger <cleger@rivosinc.com>
> ---
>  arch/riscv/include/asm/csr.h | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> index b4551a6cf7cb..26cb78dee2fd 100644
> --- a/arch/riscv/include/asm/csr.h
> +++ b/arch/riscv/include/asm/csr.h
> @@ -241,6 +241,31 @@
>  #define SMSTATEEN0_HSENVCFG		(_ULL(1) << SMSTATEEN0_HSENVCFG_SHIFT)
>  #define SMSTATEEN0_SSTATEEN0_SHIFT	63
>  #define SMSTATEEN0_SSTATEEN0		(_ULL(1) << SMSTATEEN0_SSTATEEN0_SHIFT)
> +/* HPMEVENT bits. These are accessible in S-mode via Smcdeleg/Ssccfg */
> +#ifdef CONFIG_64BIT
> +#define HPMEVENT_OF			(BIT_ULL(63))
> +#define HPMEVENT_MINH			(BIT_ULL(62))
> +#define HPMEVENT_SINH			(BIT_ULL(61))
> +#define HPMEVENT_UINH			(BIT_ULL(60))
> +#define HPMEVENT_VSINH			(BIT_ULL(59))
> +#define HPMEVENT_VUINH			(BIT_ULL(58))
> +#else
> +#define HPMEVENTH_OF			(BIT_ULL(31))
> +#define HPMEVENTH_MINH			(BIT_ULL(30))
> +#define HPMEVENTH_SINH			(BIT_ULL(29))
> +#define HPMEVENTH_UINH			(BIT_ULL(28))
> +#define HPMEVENTH_VSINH			(BIT_ULL(27))
> +#define HPMEVENTH_VUINH			(BIT_ULL(26))

Since these are rv32 bits for a 32-bit register, I think these should be
BIT() instead of BIT_ULL()

> +
> +#define HPMEVENT_OF			(HPMEVENTH_OF << 32)
> +#define HPMEVENT_MINH			(HPMEVENTH_MINH << 32)
> +#define HPMEVENT_SINH			(HPMEVENTH_SINH << 32)
> +#define HPMEVENT_UINH			(HPMEVENTH_UINH << 32)
> +#define HPMEVENT_VSINH			(HPMEVENTH_VSINH << 32)
> +#define HPMEVENT_VUINH			(HPMEVENTH_VUINH << 32)

These definitions are identical to the rv64 ones, can these be removed
and can you move the rv64 definitions to be global?

- Charlie

> +#endif
> +
> +#define SISELECT_SSCCFG_BASE		0x40
>  
>  /* mseccfg bits */
>  #define MSECCFG_PMM			ENVCFG_PMM
> @@ -322,6 +347,7 @@
>  #define CSR_SCOUNTEREN		0x106
>  #define CSR_SENVCFG		0x10a
>  #define CSR_SSTATEEN0		0x10c
> +#define CSR_SCOUNTINHIBIT	0x120
>  #define CSR_SSCRATCH		0x140
>  #define CSR_SEPC		0x141
>  #define CSR_SCAUSE		0x142
> 
> -- 
> 2.53.0-Meta
> 
> 
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


^ permalink raw reply

* Re: [PATCH v6 04/21] RISC-V: Define indirect CSR access helpers
From: Charlie Jenkins @ 2026-06-22  6:42 UTC (permalink / raw)
  To: Atish Patra
  Cc: James Clark, Rob Herring, Arnaldo Carvalho de Melo, Jiri Olsa,
	Will Deacon, Mark Rutland, Anup Patel, Namhyung Kim,
	Paul Walmsley, Krzysztof Kozlowski, Ian Rogers, linux-riscv,
	linux-kernel, linux-perf-users, Conor Dooley, devicetree,
	linux-arm-kernel
In-Reply-To: <20260608-counter_delegation-v6-4-285b72ed65a9@meta.com>

On Mon, Jun 08, 2026 at 11:01:18PM -0700, Atish Patra wrote:
> From: Atish Patra <atishp@rivosinc.com>
> 
> The indriect CSR requires multiple instructions to read/write CSR.

indirect

> Add a few helper functions for ease of usage.
> 
> Signed-off-by: Atish Patra <atishp@rivosinc.com>
> ---
>  arch/riscv/include/asm/csr_ind.h | 44 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/csr_ind.h b/arch/riscv/include/asm/csr_ind.h
> new file mode 100644
> index 000000000000..6fd7d44dc640
> --- /dev/null
> +++ b/arch/riscv/include/asm/csr_ind.h
> @@ -0,0 +1,44 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2024 Rivos Inc.

I don't think it makes sense to introduce this copyright in new commits.

- Charlie

> + */
> +
> +#ifndef _ASM_RISCV_CSR_IND_H
> +#define _ASM_RISCV_CSR_IND_H
> +
> +#include <linux/irqflags.h>
> +
> +#include <asm/csr.h>
> +
> +#define csr_ind_read(iregcsr, iselbase, iseloff) ({		\
> +	unsigned long __value = 0;				\
> +	unsigned long __flags;					\
> +	local_irq_save(__flags);				\
> +	csr_write(CSR_ISELECT, (iselbase) + (iseloff));		\
> +	__value = csr_read(iregcsr);				\
> +	local_irq_restore(__flags);				\
> +	__value;						\
> +})
> +
> +#define csr_ind_write(iregcsr, iselbase, iseloff, value) ({	\
> +	unsigned long __flags;					\
> +	local_irq_save(__flags);				\
> +	csr_write(CSR_ISELECT, (iselbase) + (iseloff));		\
> +	csr_write(iregcsr, (value));				\
> +	local_irq_restore(__flags);				\
> +})
> +
> +#define csr_ind_warl(iregcsr, iselbase, iseloff, warl_val) ({	\
> +	unsigned long __old_val = 0, __value = 0;		\
> +	unsigned long __flags;					\
> +	local_irq_save(__flags);				\
> +	csr_write(CSR_ISELECT, (iselbase) + (iseloff));		\
> +	__old_val = csr_read(iregcsr);				\
> +	csr_write(iregcsr, (warl_val));				\
> +	__value = csr_read(iregcsr);				\
> +	csr_write(iregcsr, __old_val);				\
> +	local_irq_restore(__flags);				\
> +	__value;						\
> +})
> +
> +#endif
> 
> -- 
> 2.53.0-Meta
> 
> 
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
> 


^ permalink raw reply

* Re: [PATCH v10 1/4] dt-bindings: clock: imx95-blk-ctl: Use single quotes consistently
From: Krzysztof Kozlowski @ 2026-06-22  6:39 UTC (permalink / raw)
  To: guoniu.zhou
  Cc: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
	Michael Turquette, Stephen Boyd, imx, linux-media, devicetree,
	linux-arm-kernel, linux-kernel, linux-clk, Guoniu Zhou
In-Reply-To: <20260618-csi_formatter-v10-1-f23830312ba5@oss.nxp.com>

On Thu, Jun 18, 2026 at 05:41:35PM +0800, guoniu.zhou@oss.nxp.com wrote:
> From: Guoniu Zhou <guoniu.zhou@nxp.com>
> 
> Change "clocks" to 'clocks' in the description to match the quote style
> used for property names like '#clock-cells' throughout the file.
> 
> Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
> ---
> Changes in v10:
> - New patch to fix inconsistent quote usage (Krzysztof Kozlowski)

I think this is not necessary. I comment to have consistent style for a
new code, but changing this in existing one is just too much of work for
no real benefits.

Best regards,
Krzysztof



^ permalink raw reply

* [PATCH] cpufreq: apple-soc: Add missing OPP table cleanup on init failure
From: Haoxiang Li @ 2026-06-22  6:31 UTC (permalink / raw)
  To: sven, j, neal, rafael, viresh.kumar
  Cc: asahi, linux-arm-kernel, linux-pm, linux-kernel, Haoxiang Li

apple_soc_cpufreq_init() adds the OPP table with
dev_pm_opp_of_add_table(), but some later error
paths can return without removing it.

Add the missing dev_pm_opp_of_remove_table() call
to clean up the OPP table on init failure.

Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 9396034167e5..4dae968e84df 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -260,7 +260,7 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy)
 	ret = apple_soc_cpufreq_find_cluster(policy, &reg_base, &info);
 	if (ret) {
 		dev_err(cpu_dev, "%s: failed to get cluster info: %d\n", __func__, ret);
-		return ret;
+		goto out_remove_table;
 	}
 
 	ret = dev_pm_opp_set_sharing_cpus(cpu_dev, policy->cpus);
@@ -326,6 +326,8 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy)
 	dev_pm_opp_remove_all_dynamic(cpu_dev);
 out_iounmap:
 	iounmap(reg_base);
+out_remove_table:
+	dev_pm_opp_of_remove_table(cpu_dev);
 	return ret;
 }
 
-- 
2.25.1



^ permalink raw reply related

* Re: [PATCH] arm64: dts: broadcom: bcm2712: Remove non-functional EL2 virtual timer
From: Marek Szyprowski @ 2026-06-22  6:20 UTC (permalink / raw)
  To: Daniel Drake, Florian Fainelli, Marc Zyngier
  Cc: robh, krzk+dt, conor+dt, bcm-kernel-feedback-list, devicetree,
	linux-rpi-kernel, linux-arm-kernel, andrea.porta
In-Reply-To: <89a39670-c459-4467-a032-a965bc1dea6b@reactivated.net>

On 21.06.2026 22:58, Daniel Drake wrote:
> On 21/06/2026 21:03, Florian Fainelli wrote:
>> Daniel, do you happen to know which 2712 SoC revision you have, whether this is a C0 or D0 stepping?
>>
>> We have an internal bug tracker item pertaining exactly to the virtual timer interrupt connection however it affected a sister chip (77122) and not 2712 AFAICT, now checking with the design team whether the same happened on 2712.
> Thanks for looking into this! I am using Raspberry Pi 500 with D0 stepping.
>
Here it happens on one of the first shipped Raspberry Pi5, so probably C0 stepping.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



^ permalink raw reply

* RE: [PATCH 1/8] PCI: imx6: Add skip_pwrctrl_off flag support
From: Sherry Sun @ 2026-06-22  5:52 UTC (permalink / raw)
  To: Frank Li (OSS), Sherry Sun (OSS)
  Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	Frank Li, s.hauer@pengutronix.de, kernel@pengutronix.de,
	festevam@gmail.com, Amitkumar Karwar, Neeraj Sanjay Kale,
	marcel@holtmann.org, luiz.dentz@gmail.com, Hongxing Zhu,
	l.stach@pengutronix.de, lpieralisi@kernel.org,
	kwilczynski@kernel.org, mani@kernel.org, bhelgaas@google.com,
	brgl@kernel.org, imx@lists.linux.dev, linux-pci@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org,
	linux-pm@vger.kernel.org
In-Reply-To: <ajQ64ZswbmTceIGO@SMW015318>

> On Thu, Jun 18, 2026 at 06:10:40PM +0800, Sherry Sun (OSS) wrote:
> > From: Sherry Sun <sherry.sun@nxp.com>
> >
> > Use dw_pcie::skip_pwrctrl_off to avoid powering off devices during
> > suspend to preserve wakeup capability of the devices and also not to
> > power on the devices in the init path.
> > This allows controller power-off to be skipped when some devices(e.g.
> > M.2 cards key E without auxiliary power) required to support PCIe L2
> > link state and wake-up mechanisms.
> >
> > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > ---
> >  drivers/pci/controller/dwc/pci-imx6.c | 36
> > +++++++++++++++++----------
> >  1 file changed, 23 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> > b/drivers/pci/controller/dwc/pci-imx6.c
> > index 0fa716d1ed75..ff5a9565dbbf 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -1382,16 +1382,20 @@ static int imx_pcie_host_init(struct dw_pcie_rp
> *pp)
> >  		}
> >  	}
> >
> > -	ret = pci_pwrctrl_create_devices(dev);
> > -	if (ret) {
> > -		dev_err(dev, "failed to create pwrctrl devices\n");
> > -		goto err_reg_disable;
> > +	if (!pci->suspended) {
> > +		ret = pci_pwrctrl_create_devices(dev);
> > +		if (ret) {
> > +			dev_err(dev, "failed to create pwrctrl devices\n");
> > +			goto err_reg_disable;
> > +		}
> 
> supposed create_devices only do once.
> 
> pci_pwrctrl_power_on_devices() controller on and off for difference case.
> 

Hi  Frank,
Yes, pci_pwrctrl_create_devices() is currently only called once
during imx_pcie_probe.
pci_pwrctrl_power_on_devices() is called during imx_pcie_probe
and during suspend/resume (depending on skip_pwrctrl_off flag).

Best Regards
Sherry
> >  	}
> >
> > -	ret = pci_pwrctrl_power_on_devices(dev);
> > -	if (ret) {
> > -		dev_err(dev, "failed to power on pwrctrl devices\n");
> > -		goto err_pwrctrl_destroy;
> > +	if (!pp->skip_pwrctrl_off) {
> > +		ret = pci_pwrctrl_power_on_devices(dev);
> > +		if (ret) {
> > +			dev_err(dev, "failed to power on pwrctrl devices\n");
> > +			goto err_pwrctrl_destroy;
> > +		}
> >  	}
> >
> >  	ret = imx_pcie_clk_enable(imx_pcie); @@ -1460,9 +1464,10 @@
> static
> > int imx_pcie_host_init(struct dw_pcie_rp *pp)
> >  err_clk_disable:
> >  	imx_pcie_clk_disable(imx_pcie);
> >  err_pwrctrl_power_off:
> > -	pci_pwrctrl_power_off_devices(dev);
> > +	if (!pp->skip_pwrctrl_off)
> > +		pci_pwrctrl_power_off_devices(dev);
> >  err_pwrctrl_destroy:
> > -	if (ret != -EPROBE_DEFER)
> > +	if (ret != -EPROBE_DEFER && !pci->suspended)
> >  		pci_pwrctrl_destroy_devices(dev);
> >  err_reg_disable:
> >  	if (imx_pcie->vpcie)
> > @@ -1482,7 +1487,8 @@ static void imx_pcie_host_exit(struct dw_pcie_rp
> *pp)
> >  	}
> >  	imx_pcie_clk_disable(imx_pcie);
> >
> > -	pci_pwrctrl_power_off_devices(pci->dev);
> > +	if (!pci->pp.skip_pwrctrl_off)
> > +		pci_pwrctrl_power_off_devices(pci->dev);
> >  	if (imx_pcie->vpcie)
> >  		regulator_disable(imx_pcie->vpcie);
> >  }
> > @@ -1990,12 +1996,16 @@ static int imx_pcie_probe(struct
> > platform_device *pdev)  static void imx_pcie_shutdown(struct
> > platform_device *pdev)  {
> >  	struct imx_pcie *imx_pcie = platform_get_drvdata(pdev);
> > +	struct dw_pcie *pci = imx_pcie->pci;
> > +	struct dw_pcie_rp *pp = &pci->pp;
> >
> >  	/* bring down link, so bootloader gets clean state in case of reboot */
> >  	imx_pcie_assert_core_reset(imx_pcie);
> >  	imx_pcie_assert_perst(imx_pcie, true);
> > -	pci_pwrctrl_power_off_devices(&pdev->dev);
> > -	pci_pwrctrl_destroy_devices(&pdev->dev);
> > +	if (!pp->skip_pwrctrl_off)
> > +		pci_pwrctrl_power_off_devices(&pdev->dev);
> > +	if (!pci->suspended)
> > +		pci_pwrctrl_destroy_devices(&pdev->dev);
> >  }
> >
> >  static const struct imx_pcie_drvdata drvdata[] = {
> > --
> > 2.50.1
> >
> >


^ permalink raw reply

* [PATCH] net: ixp4xx_hss: fix duplicate HDLC netdev allocation
From: Haoxiang Li @ 2026-06-22  4:30 UTC (permalink / raw)
  To: linusw, kaloz, andrew+netdev, davem, edumazet, kuba, pabeni,
	huangguangbin2, lipeng321
  Cc: linux-arm-kernel, netdev, linux-kernel, Haoxiang Li, stable

ixp4xx_hss_probe() allocates two HDLC netdevs. The first one is stored
in ndev, initialized, and registered with register_hdlc_device(). The
second one is stored in port->netdev and later used by the remove path
for unregister_hdlc_device() and free_netdev().

This means that the registered netdev is not the same object that is
unregistered and freed on remove. It also leaks the first allocation if
the second alloc_hdlcdev() call fails, and the first allocation is not
checked before ndev is used.

Older code allocated the HDLC netdev only once and stored the same object
in both the local variable and port->netdev. The buggy conversion split
this into two alloc_hdlcdev() calls. A later rename changed the local
variable name to ndev, but the underlying mismatch remained.

Fix this by allocating the HDLC netdev only once and assigning the same
object to port->netdev.

Fixes: 99ebe65eb9c0 ("net: ixp4xx_hss: move out assignment in if condition")
Cc: stable@vger.kernel.org
Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
---
 drivers/net/wan/ixp4xx_hss.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index 720c5dc889ea..7f4645ff90aa 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -1487,11 +1487,11 @@ static int ixp4xx_hss_probe(struct platform_device *pdev)
 				     "unable to get CLK internal GPIO\n");
 
 	ndev = alloc_hdlcdev(port);
-	port->netdev = alloc_hdlcdev(port);
-	if (!port->netdev) {
+	if (!ndev) {
 		err = -ENOMEM;
 		goto err_plat;
 	}
+	port->netdev = ndev;
 
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	hdlc = dev_to_hdlc(ndev);
-- 
2.25.1



^ permalink raw reply related

* Re: [RFC PATCH 0/2] kasan: hw_tags: Add option to tag only at allocation time
From: Dev Jain @ 2026-06-22  4:21 UTC (permalink / raw)
  To: Isaac Manjarres
  Cc: ryabinin.a.a, akpm, corbet, glider, andreyknvl, dvyukov,
	vincenzo.frascino, kasan-dev, linux-mm, linux-kernel, skhan,
	workflows, linux-doc, linux-arm-kernel, ryan.roberts,
	anshuman.khandual, kaleshsingh, 21cnbao, david, will,
	catalin.marinas
In-Reply-To: <aiyhb2XwMMJE3st7@google.com>



On 13/06/26 5:46 am, Isaac Manjarres wrote:
> On Fri, Jun 12, 2026 at 04:44:22AM +0000, Dev Jain wrote:
>> Introduce a boot option to tag only at allocation time of the objects. This
>> reduces KASAN MTE overhead, the tradeoff being reduced ability of
>> catching bugs.
>>
>> Now, when a memory object will be freed, it will retain the random tag it
>> had at allocation time. This compromises on catching UAF bugs, till the
>> time the object is not reallocated, at which point it will have a new
>> random tag.
>>
>> Hence, not catching "use-after-free-before-reallocation" and not catching
>> "double-free" will be the compromise for reduced KASAN overhead.
>>
>> This is an RFC because we are not clear about the performance benefit.
>>
>> Android folks, please help with testing!
>>
>> ---
>> Applies on Linus master (9716c086c8e8).
>>
>> Dev Jain (2):
>>   kasan: hw_tags: Use KASAN_PAGE_REDZONE for vmalloc redzoning
>>   kasan: hw_tags: Add boot option to elide free time poisoning
>>
>>  Documentation/dev-tools/kasan.rst |  4 +++
>>  mm/kasan/hw_tags.c                | 45 +++++++++++++++++++++++++++++--
>>  mm/kasan/kasan.h                  | 23 +++++++++++++++-
>>  3 files changed, 69 insertions(+), 3 deletions(-)
>>
>> -- 
>> 2.43.0
> 
> I tested out this series on one of our devices that has MTE support,
> and didn't see any functional issues.

Thanks for testing Isaac! Do you have the bandwidth to carry out some
performance tests? We want to see whether this patchset gets perf boost
on some HW.

> 
> One thing I did notice though, and it's independent of this patch, is
> that the vmalloc_oob is failing, but that happens even if these patches
> aren't present.
> 
> Thanks,
> Isaac



^ permalink raw reply

* Re: [PATCH v6 2/2] arm64: dts: ti: Add audio overlay for k3-j721s2-evm
From: Wang, Sen @ 2026-06-22  3:52 UTC (permalink / raw)
  To: Shah, Moteen, krzk+dt@kernel.org, robh@kernel.org,
	conor+dt@kernel.org, Menon, Nishanth, Raghavendra, Vignesh,
	kristo@kernel.org
  Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, Kumar, Udit,
	Gujulan Elango, Hari Prasath, Abhilash Chandra, Yemike
In-Reply-To: <20260619062749.1575066-3-m-shah@ti.com>

On 6/19/2026 1:27 AM, Shah, Moteen wrote:
> From: Jayesh Choudhary <j-choudhary@ti.com>
> 
> Add device tree overlay to enable analog audio support on J721S2-EVM
> using PCM3168A codec connected to McASP4 serializers.
> 
> - Add audio_refclk1 clock node to k3-j721s2-main.dtsi
> - Add nodes for sound-card, audio codec, I2C3 and McASP4
> - Add pinmux for I2C3, McASP4, AUDIO_EXT_REFCLK1 and WKUP_GPIO_0
> - Add GPIO expander (TCA6408) for codec control
> - Add GPIO hogs to route I2C3 lines and McASP serializers
> - Set idle-state to 0 in mux0 and mux1 for McASP signal routing
> 
Hi Moteen, thanks for the patch.

Reviewed-by: Sen Wang <sen@ti.com>


^ permalink raw reply

* RE: [PATCH 3/8] Bluetooth: btnxpuart: Add M.2 Bluetooth device support using pwrseq
From: Sherry Sun @ 2026-06-22  3:51 UTC (permalink / raw)
  To: Frank Li (OSS), Sherry Sun (OSS)
  Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	Frank Li, s.hauer@pengutronix.de, kernel@pengutronix.de,
	festevam@gmail.com, Amitkumar Karwar, Neeraj Sanjay Kale,
	marcel@holtmann.org, luiz.dentz@gmail.com, Hongxing Zhu,
	l.stach@pengutronix.de, lpieralisi@kernel.org,
	kwilczynski@kernel.org, mani@kernel.org, bhelgaas@google.com,
	brgl@kernel.org, imx@lists.linux.dev, linux-pci@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org,
	linux-pm@vger.kernel.org
In-Reply-To: <ajQ4oBUNGOrhcPX5@SMW015318>

> On Thu, Jun 18, 2026 at 06:10:42PM +0800, Sherry Sun (OSS) wrote:
> > From: Sherry Sun <sherry.sun@nxp.com>
> >
> > Power supply to the M.2 Bluetooth device attached to the host using
> > M.2 connector is controlled using the 'uart' pwrseq device. So add
> > support for getting the pwrseq device if the OF graph link is present.
> > Once obtained, the existing pwrseq APIs can be used to control the
> > power supplies of the
> > M.2 card.
> >
> > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > ---
> >  drivers/bluetooth/btnxpuart.c | 33 ++++++++++++++++++++++++++++++---
> >  1 file changed, 30 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/bluetooth/btnxpuart.c
> > b/drivers/bluetooth/btnxpuart.c index e7036a48ce48..1aa8972f0dab
> > 100644
> > --- a/drivers/bluetooth/btnxpuart.c
> > +++ b/drivers/bluetooth/btnxpuart.c
> > @@ -9,6 +9,8 @@
> >
> >  #include <linux/serdev.h>
> >  #include <linux/of.h>
> > +#include <linux/of_graph.h>
> > +#include <linux/pwrseq/consumer.h>
> >  #include <linux/skbuff.h>
> >  #include <linux/unaligned.h>
> >  #include <linux/firmware.h>
> > @@ -211,6 +213,7 @@ struct btnxpuart_dev {
> >
> >  	struct ps_data psdata;
> >  	struct btnxpuart_data *nxp_data;
> > +	struct pwrseq_desc *pwrseq;
> >  	struct reset_control *pdn;
> >  	struct hci_uart hu;
> >  };
> > @@ -1866,11 +1869,27 @@ static int nxp_serdev_probe(struct
> serdev_device *serdev)
> >  		return err;
> >  	}
> >
> > +	if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
> > +		struct pwrseq_desc *pwrseq;
> > +
> > +		pwrseq = devm_pwrseq_get(&serdev->ctrl->dev, "uart");
> > +		if (IS_ERR(pwrseq))
> > +			return PTR_ERR(pwrseq);
> > +
> > +		nxpdev->pwrseq = pwrseq;
> > +		err = pwrseq_power_on(pwrseq);
> > +		if (err) {
> > +			dev_err(&serdev->dev, "Failed to power on
> pwrseq\n");
> > +			return err;
> > +		}
> 
> Can you provide helper function like devm clk get and enabled?
> like devm_pwrsq_get_on()
> 
> So simple below error handle.

Ok, will try.

Best Regards
Sherry

> 
> > +	}
> > +
> >  	/* Initialize and register HCI device */
> >  	hdev = hci_alloc_dev();
> >  	if (!hdev) {
> >  		dev_err(&serdev->dev, "Can't allocate HCI device\n");
> > -		return -ENOMEM;
> > +		err = -ENOMEM;
> > +		goto err_pwrseq_power_off;
> >  	}
> >
> >  	reset_control_deassert(nxpdev->pdn);
> > @@ -1903,11 +1922,14 @@ static int nxp_serdev_probe(struct
> > serdev_device *serdev)
> >
> >  	if (hci_register_dev(hdev) < 0) {
> >  		dev_err(&serdev->dev, "Can't register HCI device\n");
> > +		err = -ENODEV;
> >  		goto probe_fail;
> >  	}
> >
> > -	if (ps_setup(hdev))
> > +	if (ps_setup(hdev)) {
> > +		err = -ENODEV;
> >  		goto probe_fail;
> > +	}
> >
> >  	hci_devcd_register(hdev, nxp_coredump, nxp_coredump_hdr,
> >  			   nxp_coredump_notify);
> > @@ -1917,7 +1939,10 @@ static int nxp_serdev_probe(struct
> > serdev_device *serdev)
> >  probe_fail:
> >  	reset_control_assert(nxpdev->pdn);
> >  	hci_free_dev(hdev);
> > -	return -ENODEV;
> > +err_pwrseq_power_off:
> > +	if (nxpdev->pwrseq)
> > +		pwrseq_power_off(nxpdev->pwrseq);
> > +	return err;
> >  }
> >
> >  static void nxp_serdev_remove(struct serdev_device *serdev) @@
> > -1944,6 +1969,8 @@ static void nxp_serdev_remove(struct serdev_device
> *serdev)
> >  	ps_cleanup(nxpdev);
> >  	hci_unregister_dev(hdev);
> >  	reset_control_assert(nxpdev->pdn);
> > +	if (nxpdev->pwrseq)
> > +		pwrseq_power_off(nxpdev->pwrseq);
> >  	hci_free_dev(hdev);
> >  }
> >
> > --
> > 2.50.1
> >
> >


^ permalink raw reply

* RE: [PATCH 0/8] Add PCIe M.2 Key E connector support for NXP i.MX boards
From: Sherry Sun @ 2026-06-22  3:18 UTC (permalink / raw)
  To: Bartosz Golaszewski, Sherry Sun (OSS)
  Cc: imx@lists.linux.dev, linux-pci@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org,
	linux-pm@vger.kernel.org, robh@kernel.org, krzk+dt@kernel.org,
	conor+dt@kernel.org, Frank Li, s.hauer@pengutronix.de,
	kernel@pengutronix.de, festevam@gmail.com, Amitkumar Karwar,
	Neeraj Sanjay Kale, marcel@holtmann.org, luiz.dentz@gmail.com,
	Hongxing Zhu, l.stach@pengutronix.de, lpieralisi@kernel.org,
	kwilczynski@kernel.org, mani@kernel.org, bhelgaas@google.com
In-Reply-To: <CAMRc=MfsNa4itdpyGtR16wMb+wMkJwg+9=QJF2-oOoVVfFCF3g@mail.gmail.com>

> On Thu, 18 Jun 2026 12:10:39 +0200, "Sherry Sun (OSS)"
> <sherry.sun@oss.nxp.com> said:
> > From: Sherry Sun <sherry.sun@nxp.com>
> >
> > This series adds support for NXP Wi-Fi/BT combo chips (88W9098, AW693)
> > inserted into PCIe M.2 Key E connectors on several i.MX EVK/MEK boards.
> >
> > For M.2 cards that rely on PCIe L2 link state and wake-up mechanisms,
> > the card must remain powered during suspend. Patch 1 uses the existing
> > dw_pcie_rp::skip_pwrctrl_off flag to skip power-off during suspend and
> > skip power-on during the init path.
> >
> > Alsp the btnxpuart driver is extended to obtain a pwrseq descriptor
> > via the OF graph on the UART controller device in patch 2.
> >
> > Sherry Sun (8):
> >   PCI: imx6: Add skip_pwrctrl_off flag support
> >   power: sequencing: pcie-m2: Add PCI ID for NXP 88W9098 and AW693
> >     Bluetooth
> 
> Can this be applied independently without build-time issues?

Hi Bart,

Yes, this patch can be applied independently, I was able to successfully
build it based on the following base-commit:
3ce97bd3c4f18608335e709c24d6a40e7036cab8.

However, please note that it may conflict with the following patch when
applied: https://lore.kernel.org/all/20260617143055.820096-1-wei.deng@oss.qualcomm.com/.

Best Regards
Sherry

> 
> >   Bluetooth: btnxpuart: Add M.2 Bluetooth device support using pwrseq
> >   arm64: dts: imx8mq-evk: Describe the PCIe M.2 Key E connector
> >   arm64: dts: imx95-19x19-evk: Describe the PCIe M.2 Key E connector
> >   arm64: dts: imx8dxl-evk: Describe the PCIe M.2 Key E connector
> >   arm64: dts: imx8qm-mek: Describe the PCIe M.2 Key E connector
> >   arm64: dts: imx8qxp-mek: Describe the PCIe M.2 Key E connector
> >
> >  arch/arm64/boot/dts/freescale/imx8dxl-evk.dts | 56 +++++++++++++-----
> > arch/arm64/boot/dts/freescale/imx8mq-evk.dts  | 44 ++++++++++++--
> > arch/arm64/boot/dts/freescale/imx8qm-mek.dts  | 58 ++++++++++++++-----
> > arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 54 ++++++++++++-----
> >  .../boot/dts/freescale/imx95-19x19-evk.dts    | 55 +++++++++++++-----
> >  drivers/bluetooth/btnxpuart.c                 | 33 ++++++++++-
> >  drivers/pci/controller/dwc/pci-imx6.c         | 36 +++++++-----
> >  drivers/power/sequencing/pwrseq-pcie-m2.c     |  4 ++
> >  8 files changed, 264 insertions(+), 76 deletions(-)
> >
> > --
> > 2.50.1
> >
> >

^ permalink raw reply

* [PATCH] irqchip/gic-v3-its: Add Altera Agilex5 DMA workaround
From: muhammad.nazim.amirul.nazle.asmade @ 2026-06-22  2:49 UTC (permalink / raw)
  To: maz, tglx
  Cc: catalin.marinas, will, heiko, linux-arm-kernel, linux-kernel,
	linux-rockchip, adrian.ho.yin.ng

From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>

Altera Agilex5 GIC600 integration has DDR addressing limitation where
only the first 40 bits of physical address can be accessible. Extend
existing dma32 quirk in driver to support Agilex5.

Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
---
 arch/arm64/Kconfig               | 11 +++++++++++
 drivers/irqchip/irq-gic-v3-its.c | 22 +++++++++++++++-------
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b3afe0688919..5d3216b718fe 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1391,6 +1391,17 @@ config ROCKCHIP_ERRATUM_3568002
 
 	  If unsure, say Y.
 
+config ALTERA_SOCFPGA_AGILEX5_ERRATUM
+	bool "Altera SoCFPGA Agilex5: GIC600 can not access physical addresses higher than 4GB"
+	default y
+	help
+	  On SoCFPGA Agilex5 platforms, the integrated GIC600 is limited to
+	  32-bit AXI addressing and cannot access memory above 4GB. As a
+	  result, any GIC-visible resources placed outside this range may
+	  not be accessible and can lead to incorrect operation.
+
+	  If unsure, say Y.
+
 config ROCKCHIP_ERRATUM_3588001
 	bool "Rockchip 3588001: GIC600 can not support shareability attributes"
 	default y
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index b57d81ad33a0..db69e6ec98d8 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -4890,10 +4890,20 @@ static bool __maybe_unused its_enable_quirk_hip09_162100801(void *data)
 	return true;
 }
 
-static bool __maybe_unused its_enable_rk3568002(void *data)
+static bool __maybe_unused its_enable_dma32_quirk(void *data)
 {
-	if (!of_machine_is_compatible("rockchip,rk3566") &&
-	    !of_machine_is_compatible("rockchip,rk3568"))
+	static const char * const compatible[] = {
+#ifdef CONFIG_ROCKCHIP_ERRATUM_3568002
+		"rockchip,rk3566",
+		"rockchip,rk3568",
+#endif
+#ifdef CONFIG_ALTERA_SOCFPGA_AGILEX5_ERRATUM
+		"intel,socfpga-agilex5",
+#endif
+		NULL
+	};
+
+	if (!of_machine_compatible_match(compatible))
 		return false;
 
 	gfp_flags_quirk |= GFP_DMA32;
@@ -4968,14 +4978,12 @@ static const struct gic_quirk its_quirks[] = {
 		.property = "dma-noncoherent",
 		.init   = its_set_non_coherent,
 	},
-#ifdef CONFIG_ROCKCHIP_ERRATUM_3568002
 	{
-		.desc   = "ITS: Rockchip erratum RK3568002",
+		.desc   = "ITS: GIC600 integration limited to 32bit",
 		.iidr   = 0x0201743b,
 		.mask   = 0xffffffff,
-		.init   = its_enable_rk3568002,
+		.init   = its_enable_dma32_quirk,
 	},
-#endif
 	{
 	}
 };
-- 
2.43.7



^ permalink raw reply related

* Re: [PATCH v4 4/6] drm/verisilicon: add DC8000 (DCUltraLite) display controller support
From: Joey Lu @ 2026-06-22  2:30 UTC (permalink / raw)
  To: Icenowy Zheng, maarten.lankhorst, mripard, tzimmermann, airlied,
	simona, robh, krzk+dt, conor+dt, Michael Turquette, Stephen Boyd,
	Brian Masney
  Cc: ychuang3, schung, yclu4, dri-devel, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk
In-Reply-To: <0bb460aefb97e44cc0890a7841b8d217349143de.camel@iscas.ac.cn>


On 6/18/2026 6:33 PM, Icenowy Zheng wrote:
> (CC'ed clk maintainers for weird clock gate bit)
>
> 在 2026-06-17三的 18:35 +0800,Joey Lu写道:
>> On 6/15/2026 4:51 PM, Icenowy Zheng wrote:
>>> 在 2026-06-15一的 14:50 +0800,Joey Lu写道:
>>>> The Nuvoton MA35D1 SoC integrates a Verisilicon DCUltraLite
>>>> display
>>>> controller whose register layout differs from the DC8200 in
>>>> several
>>>> important ways:
>>>>
>>>> 1. No CONFIG_EX commit path: framebuffer updates use the enable
>>>> (bit
>>>> 0)
>>>>      and reset (bit 4) bits in FB_CONFIG instead of the DC8200
>>>> staging
>>>>      registers (FB_CONFIG_EX, FB_TOP_LEFT, FB_BOTTOM_RIGHT,
>>>>      FB_BLEND_CONFIG, PANEL_CONFIG_EX).
>>>>
>>>> 2. No PANEL_START register: panel output starts when
>>>>      PANEL_CONFIG.RUNNING is set; there is no multi-display sync
>>>> start
>>>>      register.
>>>>
>>>> 3. Different IRQ registers: DCUltraLite uses DISP_IRQ_STA
>>>> (0x147C) /
>>>>      DISP_IRQ_EN (0x1480) versus DC8200's TOP_IRQ_ACK (0x0010) /
>>>>      TOP_IRQ_EN (0x0014).
>>>>
>>>> 4. Per-frame commit cycle: DCUltraLite requires the VALID bit in
>>>>      FB_CONFIG to be set at the start of each atomic commit
>>>> (crtc_begin)
>>>>      and cleared after (crtc_flush).
>>>>
>>>> 5. Simpler clock topology: only 'core' (bus gate) and 'pix0'
>>>> (pixel
>>>>      divider) clocks; no axi or ahb clocks required.  Make axi_clk
>>>> and
>>>>      ahb_clk optional (devm_clk_get_optional_enabled) so DC8000
>>>> nodes
>>>>      without those clocks are handled gracefully.
>>>>
>>>> Add vs_dc8000.c implementing the vs_dc_funcs vtable for the above
>>>> differences.  The probe now selects vs_dc8000_funcs when the
>>>> identified
>>>> generation is VSDC_GEN_DC8000 (DCUltraLite reads model 0x0,
>>>> revision 0x5560, customer_id 0x305).
>>>>
>>>> Signed-off-by: Joey Lu <a0987203069@gmail.com>
>>>> ---
>>>>    drivers/gpu/drm/verisilicon/Makefile    |  2 +-
>>>>    drivers/gpu/drm/verisilicon/vs_dc.c     |  9 ++-
>>>>    drivers/gpu/drm/verisilicon/vs_dc.h     |  1 +
>>>>    drivers/gpu/drm/verisilicon/vs_dc8000.c | 78
>>>> +++++++++++++++++++++++++
>>>>    4 files changed, 86 insertions(+), 4 deletions(-)
>>>>    create mode 100644 drivers/gpu/drm/verisilicon/vs_dc8000.c
>>>>
>>>> diff --git a/drivers/gpu/drm/verisilicon/Makefile
>>>> b/drivers/gpu/drm/verisilicon/Makefile
>>>> index 9d4cd16452fa..d2fd8e4dff24 100644
>>>> --- a/drivers/gpu/drm/verisilicon/Makefile
>>>> +++ b/drivers/gpu/drm/verisilicon/Makefile
>>>> @@ -1,6 +1,6 @@
>>>>    # SPDX-License-Identifier: GPL-2.0-only
>>>>    
>>>> -verisilicon-dc-objs := vs_bridge.o vs_crtc.o vs_dc.o vs_dc8200.o
>>>> vs_drm.o vs_hwdb.o \
>>>> +verisilicon-dc-objs := vs_bridge.o vs_crtc.o vs_dc.o vs_dc8200.o
>>>> vs_dc8000.o vs_drm.o vs_hwdb.o \
>>>>    	vs_plane.o vs_primary_plane.o vs_cursor_plane.o
>>>>    
>>>>    obj-$(CONFIG_DRM_VERISILICON_DC) += verisilicon-dc.o
>>>> diff --git a/drivers/gpu/drm/verisilicon/vs_dc.c
>>>> b/drivers/gpu/drm/verisilicon/vs_dc.c
>>>> index 9729b693d360..9499fffbca58 100644
>>>> --- a/drivers/gpu/drm/verisilicon/vs_dc.c
>>>> +++ b/drivers/gpu/drm/verisilicon/vs_dc.c
>>>> @@ -90,13 +90,13 @@ static int vs_dc_probe(struct platform_device
>>>> *pdev)
>>>>    		return PTR_ERR(dc->core_clk);
>>>>    	}
>>>>    
>>>> -	dc->axi_clk = devm_clk_get_enabled(dev, "axi");
>>>> +	dc->axi_clk = devm_clk_get_optional_enabled(dev, "axi");
>>>>    	if (IS_ERR(dc->axi_clk)) {
>>>>    		dev_err(dev, "can't get axi clock\n");
>>>>    		return PTR_ERR(dc->axi_clk);
>>>>    	}
>>>>    
>>>> -	dc->ahb_clk = devm_clk_get_enabled(dev, "ahb");
>>>> +	dc->ahb_clk = devm_clk_get_optional_enabled(dev, "ahb");
>>> Please make the clock change a separated patch for atomicity.
>>>
>>> BTW the MA35D1 manual's clock tree shows that DCUltra appears on
>>> AXI2
>>> ACLK, AHB_HCLK2, behind a mux of SYS-PLL/EPLL-DIV2 (which seems to
>>> be
>>> the core clock), and behind a divider (which seems to be the pixel
>>> clock).
>>>
>>> However it's weird that only one DCUltra Clock Enable Bit exists
>>> despite both bus clocks have "ICG" (I think it means "Integrated
>>> Clock
>>> Gating"). In addition the linux clk-ma35d1 driver assigns
>>> "dcu_gate" as
>>> a downstream of "dcu_mux", although the Figure 6.5-2 in the TRM
>>> shows
>>> no ICG after the "Display core CLK" mux.
>>>
>>> Is the two bus clocks controlled by a single gate bit, and is the
>>> bit
>>> also gating DC core clock?
>>>
>>> Thanks,
>>> Icenowy
>> I will split the axi/ahb optional-clock change into its own patch in
>> v5
>> for atomicity.
>> Regarding the MA35D1 clock tree: from the TRM, the single "dcu_gate"
>> bit
>> gates both bus clocks (AXI ACLK and AHB HCLK) together with the
>> display
>> core clock through the same ICG cell. The clk-ma35d1 driver exposes
>> only
>> "dcu_gate" (downstream of "dcu_mux") and does not provide separate
> Then it's one of the case that the clock tree doesn't properly
> represent the hardware, which is bad. However, as three gates share the
> same bit, I am not sure how to represent such kind of thing in the
> common clk framework.
>
>> axi/ahb clock entries. Therefore the MA35D1 DT binding will use only
>> two
>> clocks ("core" and "pix0"); making axi and ahb optional in the driver
>> is the correct approach, and this will be stated clearly in the
>>   split-out patch.
> I agree to make them optional, although these two clocks do exist in
> the hardware of MA35D1.
>
> Thanks,
> Icenowy
As mentioned in the DT binding reply, the absence of separate AXI/AHB 
clock entries for DCU in clk driver is due to the hardware design 
constraint of a single shared enable bit, not a driver oversight. In v5, 
the axi and ahb clock fetches in `vs_dc_probe` will be split into their 
own patch and made optional via `devm_clk_get_optional_enabled`, with a 
comment explaining that on MA35D1 the AXI and AHB bus clocks share the 
single `dcu_gate` enable bit and are therefore not separately exposed by 
the clock driver.
>>>>    	if (IS_ERR(dc->ahb_clk)) {
>>>>    		dev_err(dev, "can't get ahb clock\n");
>>>>    		return PTR_ERR(dc->ahb_clk);


^ permalink raw reply

* Re: [PATCH v4 1/6] dt-bindings: display: verisilicon, dc: generalize for single-output variants
From: Joey Lu @ 2026-06-22  2:28 UTC (permalink / raw)
  To: Icenowy Zheng, maarten.lankhorst, mripard, tzimmermann, airlied,
	simona, robh, krzk+dt, conor+dt
  Cc: ychuang3, schung, yclu4, dri-devel, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <b08277e8a9350f6c68c9774b1b6185b1eb71cd1e.camel@iscas.ac.cn>


On 6/18/2026 6:24 PM, Icenowy Zheng wrote:
> 在 2026-06-17三的 18:25 +0800,Joey Lu写道:
>> On 6/15/2026 4:19 PM, Icenowy Zheng wrote:
>>> 在 2026-06-15一的 14:49 +0800,Joey Lu写道:
>>>> The existing schema hard-codes the five-clock/three-reset/dual-
>>>> port
>>>> topology of the DC8200 IP block, preventing reuse for single-
>>>> output
>>>> variants such as the Verisilicon DCUltraLite used in the Nuvoton
>>>> MA35D1
>>>> SoC.
>>>>
>>>> Rework the schema so that variant-specific constraints are
>>>> expressed
>>>> via
>>>> allOf/if blocks:
>>>>
>>>> - Add nuvoton,ma35d1-dcu to the SoC-specific compatible enum.
>>>> The
>>>>     generic verisilicon,dc fallback remains the driver-binding
>>>> string.
>>>> - Move clock and reset items descriptions into the per-variant
>>>> allOf/if
>>>>     blocks; keep only minItems/maxItems at the top level so the
>>>> base
>>>> schema
>>>>     accepts all variants.
>>>> - Restore full items lists for clock-names and reset-names at the
>>>> top
>>>>     level with minItems so the names are validated against the
>>>> descriptions.
>>>> - Keep ports in the global required list and keep
>>>> additionalProperties: false.
>>>> - Add an allOf/if block for thead,th1520-dc8200: five-clock
>>>> (core,
>>>> axi,
>>>>     ahb, pix0, pix1), three-reset (core, axi, ahb), required
>>>> resets.
>>>> - Add an allOf/if block for nuvoton,ma35d1-dcu: two-clock (core,
>>>> pix0),
>>>>     one-reset (core), required resets.
>>>>
>>>> Signed-off-by: Joey Lu <a0987203069@gmail.com>
>>>> ---
>>>>    .../bindings/display/verisilicon,dc.yaml      | 80
>>>> +++++++++++++++++--
>>>>    1 file changed, 73 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git
>>>> a/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
>>>> b/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
>>>> index 9dc35ab973f2..0c41286b8223 100644
>>>> ---
>>>> a/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
>>>> +++
>>>> b/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
>>>> @@ -17,6 +17,7 @@ properties:
>>>>        items:
>>>>          - enum:
>>>>              - thead,th1520-dc8200
>>>> +          - nuvoton,ma35d1-dcu
>>>>          - const: verisilicon,dc # DC IPs have discoverable
>>>> ID/revision
>>>> registers
>>>>    
>>>>      reg:
>>>> @@ -26,14 +27,12 @@ properties:
>>>>        maxItems: 1
>>>>    
>>>>      clocks:
>>>> -    items:
>>>> -      - description: DC Core clock
>>>> -      - description: DMA AXI bus clock
>>>> -      - description: Configuration AHB bus clock
>>>> -      - description: Pixel clock of output 0
>>>> -      - description: Pixel clock of output 1
>>> Clock descriptions should still be in the global part instead of
>>> the
>>> per-compatible part.
>>>
>>> In the per-compatible part, clock-names should be constraint for
>>> SoCs.
>> I will move the `items:` clock descriptions back into the global
>> `clocks:` property, covering all five possible clocks. In the
>> per-compatible sections I will remove the description items and only
>> constrain `clocks: minItems/maxItems` and `clock-names:
>> minItems/maxItems`; for nuvoton,ma35d1-dcu I will additionally
>> override
>> `clock-names: items:` to the two names actually used (core, pix0).
> Yes, this should be the correct practice, although I wonder whether the
> minItems and maxItems properties are needed globally (because these two
> seem to have default implicit value).
>
> BTW the MA35D1 manual in fact shows 4 clocks for "DCUltra" in the clock
> tree, maybe the DT binding needs to be reconsidered?
>
> Thanks,
> Icenowy
I will drop the global `minItems`/`maxItems` on `clocks` and 
`clock-names` in v5, as they are redundant with the implicit defaults.

Regarding the 4-clock question: the TRM clock tree diagram does show 
four paths reaching DCUltra (display core mux/gate, AXI ACLK, AHB HCLK, 
and the pixel clock divider). However, the MA35D1 hardware provides only 
one software-controllable enable bit (SYSCLK0[26]) that gates the core 
clock together with the AXI and AHB bus clocks through shared ICG cells; 
there are no separate register bits for the bus clocks alone. Due to 
this hardware design constraint, the `clk-ma35d1` driver is 
intentionally designed to register only three DCU-related CCF nodes: 
`dcu_mux` (ID 61, an internal routing mux), `dcu_gate` (ID 62, the 
single gate at SYSCLK0 bit 26), and `dcup_div` (ID 63, the pixel divider 
from VPLL at CLKDIV0[18:16]), with no independent AXI or AHB gate 
entries for DCU. Since the DT binding can only reference clock handles 
that the platform clock driver actually provides, the MA35D1 binding 
will remain at two clock entries: "core" mapped to `DCU_GATE` and "pix0" 
mapped to `DCUP_DIV`.

Thanks.

>
>>>> +    minItems: 2
>>>> +    maxItems: 5
>>>>    
>>>>      clock-names:
>>>> +    minItems: 2
>>>> +    maxItems: 5
>>>>        items:
>>>>          - const: core
>>>>          - const: axi


^ permalink raw reply

* [PATCH v5 3/4] reset: cix: add sky1 audss auxiliary reset driver
From: joakim.zhang @ 2026-06-22  2:25 UTC (permalink / raw)
  To: mturquette, sboyd, bmasney, robh, krzk+dt, conor+dt, p.zabel,
	gary.yang
  Cc: cix-kernel-upstream, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel, Joakim Zhang
In-Reply-To: <20260622022520.3127103-1-joakim.zhang@cixtech.com>

From: Joakim Zhang <joakim.zhang@cixtech.com>

Add an auxiliary reset controller driver for the AUDSS CRU. Sixteen
software reset lines for audio subsystem peripherals are controlled
through one register in the CRU register map.

The driver is created by the AUDSS clock platform driver and registers
the reset controller on the CRU device node.

Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
 drivers/reset/Kconfig            |  14 +++
 drivers/reset/Makefile           |   1 +
 drivers/reset/reset-sky1-audss.c | 192 +++++++++++++++++++++++++++++++
 3 files changed, 207 insertions(+)
 create mode 100644 drivers/reset/reset-sky1-audss.c

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index d009eb0849a3..f74859b292ae 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -300,6 +300,20 @@ config RESET_SKY1
 	help
 	  This enables the reset controller for Cix Sky1.
 
+config RESET_SKY1_AUDSS
+	tristate "Cix Sky1 Audio Subsystem reset controller"
+	depends on ARCH_CIX || COMPILE_TEST
+	select AUXILIARY_BUS
+	select REGMAP_MMIO
+	default CLK_SKY1_AUDSS
+	help
+	  Support for block-level software reset lines in the Cix Sky1
+	  Audio Subsystem (AUDSS) Clock and Reset Unit. Sixteen reset
+	  outputs for audio peripherals are controlled through the CRU
+	  register map. The driver binds as an auxiliary device from
+	  the AUDSS clock driver. Say M or Y here if you want to build
+	  this driver.
+
 config RESET_SOCFPGA
 	bool "SoCFPGA Reset Driver" if COMPILE_TEST && (!ARM || !ARCH_INTEL_SOCFPGA)
 	default ARM && ARCH_INTEL_SOCFPGA
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 3e52569bd276..e81407ea3e29 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_RESET_RZV2H_USB2PHY) += reset-rzv2h-usb2phy.o
 obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_SKY1) += reset-sky1.o
+obj-$(CONFIG_RESET_SKY1_AUDSS) += reset-sky1-audss.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
 obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
 obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
diff --git a/drivers/reset/reset-sky1-audss.c b/drivers/reset/reset-sky1-audss.c
new file mode 100644
index 000000000000..f29fe3554ec1
--- /dev/null
+++ b/drivers/reset/reset-sky1-audss.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cix Sky1 Audio Subsystem reset controller driver
+ *
+ * Copyright 2026 Cix Technology Group Co., Ltd.
+ */
+
+#include <dt-bindings/reset/cix,sky1-audss-reset.h>
+
+#include <linux/auxiliary_bus.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#define SKY1_RESET_SLEEP_MIN_US		50
+#define SKY1_RESET_SLEEP_MAX_US		100
+
+#define AUDSS_SW_RST			0x78
+
+struct sky1_audss_reset_map {
+	unsigned int offset;
+	unsigned int mask;
+};
+
+struct sky1_audss_reset {
+	struct reset_controller_dev rcdev;
+	struct regmap *regmap;
+	const struct sky1_audss_reset_map *map;
+};
+
+static const struct sky1_audss_reset_map sky1_audss_reset_map[] = {
+	[AUDSS_I2S0_SW_RST]   = { AUDSS_SW_RST, BIT(0) },
+	[AUDSS_I2S1_SW_RST]   = { AUDSS_SW_RST, BIT(1) },
+	[AUDSS_I2S2_SW_RST]   = { AUDSS_SW_RST, BIT(2) },
+	[AUDSS_I2S3_SW_RST]   = { AUDSS_SW_RST, BIT(3) },
+	[AUDSS_I2S4_SW_RST]   = { AUDSS_SW_RST, BIT(4) },
+	[AUDSS_I2S5_SW_RST]   = { AUDSS_SW_RST, BIT(5) },
+	[AUDSS_I2S6_SW_RST]   = { AUDSS_SW_RST, BIT(6) },
+	[AUDSS_I2S7_SW_RST]   = { AUDSS_SW_RST, BIT(7) },
+	[AUDSS_I2S8_SW_RST]   = { AUDSS_SW_RST, BIT(8) },
+	[AUDSS_I2S9_SW_RST]   = { AUDSS_SW_RST, BIT(9) },
+	[AUDSS_WDT_SW_RST]    = { AUDSS_SW_RST, BIT(10) },
+	[AUDSS_TIMER_SW_RST]  = { AUDSS_SW_RST, BIT(11) },
+	[AUDSS_MB0_SW_RST]    = { AUDSS_SW_RST, BIT(12) },
+	[AUDSS_MB1_SW_RST]    = { AUDSS_SW_RST, BIT(13) },
+	[AUDSS_HDA_SW_RST]    = { AUDSS_SW_RST, BIT(14) },
+	[AUDSS_DMAC_SW_RST]   = { AUDSS_SW_RST, BIT(15) },
+};
+
+static struct sky1_audss_reset *to_sky1_audss_reset(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct sky1_audss_reset, rcdev);
+}
+
+static int sky1_audss_reset_set(struct reset_controller_dev *rcdev,
+				unsigned long id, bool assert)
+{
+	struct sky1_audss_reset *priv = to_sky1_audss_reset(rcdev);
+	const struct sky1_audss_reset_map *signal = &priv->map[id];
+	unsigned int value = assert ? 0 : signal->mask;
+
+	return regmap_update_bits(priv->regmap, signal->offset, signal->mask, value);
+}
+
+static int sky1_audss_reset_assert(struct reset_controller_dev *rcdev,
+				   unsigned long id)
+{
+	sky1_audss_reset_set(rcdev, id, true);
+	usleep_range(SKY1_RESET_SLEEP_MIN_US, SKY1_RESET_SLEEP_MAX_US);
+	return 0;
+}
+
+static int sky1_audss_reset_deassert(struct reset_controller_dev *rcdev,
+				     unsigned long id)
+{
+	sky1_audss_reset_set(rcdev, id, false);
+	usleep_range(SKY1_RESET_SLEEP_MIN_US, SKY1_RESET_SLEEP_MAX_US);
+	return 0;
+}
+
+static int sky1_audss_reset(struct reset_controller_dev *rcdev,
+			    unsigned long id)
+{
+	sky1_audss_reset_assert(rcdev, id);
+	sky1_audss_reset_deassert(rcdev, id);
+	return 0;
+}
+
+static int sky1_audss_reset_status(struct reset_controller_dev *rcdev,
+				   unsigned long id)
+{
+	struct sky1_audss_reset *priv = to_sky1_audss_reset(rcdev);
+	const struct sky1_audss_reset_map *signal = &priv->map[id];
+	unsigned int value;
+
+	regmap_read(priv->regmap, signal->offset, &value);
+	return !!(value & signal->mask);
+}
+
+static const struct reset_control_ops sky1_audss_reset_ops = {
+	.reset    = sky1_audss_reset,
+	.assert   = sky1_audss_reset_assert,
+	.deassert = sky1_audss_reset_deassert,
+	.status   = sky1_audss_reset_status,
+};
+
+static const struct regmap_config sky1_audss_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+};
+
+static void sky1_audss_reset_iounmap(void *data)
+{
+	iounmap(data);
+}
+
+static int sky1_audss_reset_get_regmap(struct sky1_audss_reset *priv)
+{
+	struct device *dev = priv->rcdev.dev;
+	void __iomem *base;
+	int ret;
+
+	priv->regmap = dev_get_regmap(dev->parent, NULL);
+	if (priv->regmap)
+		return 0;
+
+	base = of_iomap(dev->parent->of_node, 0);
+	if (!base)
+		return dev_err_probe(dev, -ENOMEM, "failed to iomap address space\n");
+
+	ret = devm_add_action_or_reset(dev, sky1_audss_reset_iounmap, base);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to register iounmap action\n");
+
+	priv->regmap = devm_regmap_init_mmio(dev, base, &sky1_audss_regmap_config);
+	if (IS_ERR(priv->regmap))
+		return dev_err_probe(dev, PTR_ERR(priv->regmap),
+				     "failed to initialize regmap\n");
+
+	return 0;
+}
+
+static int sky1_audss_reset_probe(struct auxiliary_device *adev,
+				  const struct auxiliary_device_id *id)
+{
+	struct sky1_audss_reset *priv;
+	struct device *dev = &adev->dev;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->map = sky1_audss_reset_map;
+	priv->rcdev.owner = THIS_MODULE;
+	priv->rcdev.nr_resets = ARRAY_SIZE(sky1_audss_reset_map);
+	priv->rcdev.ops = &sky1_audss_reset_ops;
+	priv->rcdev.of_node = dev->parent->of_node;
+	priv->rcdev.dev = dev;
+	priv->rcdev.of_reset_n_cells = 1;
+
+	dev_set_drvdata(dev, priv);
+
+	ret = sky1_audss_reset_get_regmap(priv);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to get regmap\n");
+
+	return devm_reset_controller_register(dev, &priv->rcdev);
+}
+
+static const struct auxiliary_device_id sky1_audss_reset_ids[] = {
+	{ .name = "clk_sky1_audss.reset" },
+	{ }
+};
+MODULE_DEVICE_TABLE(auxiliary, sky1_audss_reset_ids);
+
+static struct auxiliary_driver sky1_audss_reset_driver = {
+	.probe = sky1_audss_reset_probe,
+	.id_table = sky1_audss_reset_ids,
+};
+
+module_auxiliary_driver(sky1_audss_reset_driver);
+
+MODULE_AUTHOR("Joakim Zhang <joakim.zhang@cixtech.com>");
+MODULE_DESCRIPTION("Cix Sky1 Audio Subsystem reset driver");
+MODULE_LICENSE("GPL");
-- 
2.50.1



^ permalink raw reply related


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