Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH net-next v2 2/9] dt-bindings: net: lan9645x: add LAN9645X switch bindings
From: Jens Emil Schulz Ostergaard @ 2026-04-08 14:59 UTC (permalink / raw)
  To: Rob Herring
  Cc: UNGLinuxDriver, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Krzysztof Kozlowski, Conor Dooley, Woojung Huh, Russell King,
	Steen Hegelund, Daniel Machon, linux-kernel, netdev, devicetree
In-Reply-To: <20260407171854.GA2970003-robh@kernel.org>

On Tue, 2026-04-07 at 12:18 -0500, Rob Herring wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Tue, Mar 24, 2026 at 11:46:45AM +0100, Jens Emil Schulz Østergaard wrote:
> > Add bindings for LAN9645X switch. We use a fallback compatible for the
> > smallest SKU microchip,lan96455s-switch.
> > 
> > Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
> > Signed-off-by: Jens Emil Schulz Østergaard <jensemil.schulzostergaard@microchip.com>
> > ---
> > Changes in v2:
> > - rename file to microchip,lan96455s-switch.yaml
> > - remove led vendor property
> > - add {rx,tx}-internal-delay-ps for rgmii delay
> > - remove labels from example
> > - remove container node from example
> > ---
> >  .../net/dsa/microchip,lan96455s-switch.yaml        | 119 +++++++++++++++++++++
> >  MAINTAINERS                                        |   1 +
> >  2 files changed, 120 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/net/dsa/microchip,lan96455s-switch.yaml b/Documentation/devicetree/bindings/net/dsa/microchip,lan96455s-switch.yaml
> > new file mode 100644
> > index 000000000000..0282e25c05d4
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/dsa/microchip,lan96455s-switch.yaml
> > @@ -0,0 +1,119 @@
> > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/dsa/microchip,lan96455s-switch.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Microchip LAN9645x Ethernet switch
> > +
> > +maintainers:
> > +  - Jens Emil Schulz Østergaard <jensemil.schulzostergaard@microchip.com>
> > +
> > +description: |
> 
> Don't need '|'

I will remove this.

> 
> > +  The LAN9645x switch is a multi-port Gigabit AVB/TSN Ethernet switch with
> > +  five integrated 10/100/1000Base-T PHYs. In addition to the integrated PHYs,
> > +  it supports up to 2 RGMII/RMII, up to 2 BASE-X/SERDES/2.5GBASE-X and one
> > +  Quad-SGMII interfaces.
> > +
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - enum:
> > +          - microchip,lan96455s-switch
> > +      - items:
> > +          - enum:
> > +              - microchip,lan96455f-switch
> > +              - microchip,lan96457f-switch
> > +              - microchip,lan96459f-switch
> > +              - microchip,lan96457s-switch
> > +              - microchip,lan96459s-switch
> > +          - const: microchip,lan96455s-switch
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +$ref: dsa.yaml#
> 
> Since you don't have any custom properties (just constraints), this ref
> should be "dsa.yaml#/$defs/ethernet-ports".

Right, I will update the ref.

> 
> > +
> > +patternProperties:
> > +  "^(ethernet-)?ports$":
> 
> For a new binding, use the preferred name which is ethernet-ports. ports
> and port collide with the graph binding.
> 

OK, I will use ethernet-ports and move it from patternProperties to properties.

> > +    type: object
> > +    additionalProperties: true
> > +    patternProperties:
> > +      "^(ethernet-)?port@[0-8]$":
> 
> And 'ethernet-port'

I will change this and update the example.

> 
> > +        type: object
> > +        description: Ethernet switch ports
> > +
> > +        $ref: dsa-port.yaml#
> > +
> > +        properties:
> > +          rx-internal-delay-ps:
> > +            const: 2000
> > +
> > +          tx-internal-delay-ps:
> > +            const: 2000
> > +
> > +        unevaluatedProperties: false
> 
> Place this after the $ref.

I will move this.

> 
> > +
> > +oneOf:
> > +  - required:
> > +      - ports
> > +  - required:
> > +      - ethernet-ports
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    ethernet-switch@4000 {
> > +        compatible = "microchip,lan96459f-switch", "microchip,lan96455s-switch";
> > +        reg = <0x4000 0x244>;
> > +
> > +        ethernet-ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +
> > +            port@0 {
> > +                reg = <0>;
> > +                phy-mode = "gmii";
> > +                phy-handle = <&cuphy0>;
> > +            };
> > +
> > +            port@1 {
> > +                reg = <1>;
> > +                phy-mode = "gmii";
> > +                phy-handle = <&cuphy1>;
> > +            };
> > +
> > +            port@2 {
> > +                reg = <2>;
> > +                phy-mode = "gmii";
> > +                phy-handle = <&cuphy2>;
> > +            };
> > +
> > +            port@3 {
> > +                reg = <3>;
> > +                phy-mode = "gmii";
> > +                phy-handle = <&cuphy3>;
> > +            };
> > +
> > +            port@7 {
> > +                reg = <7>;
> > +                phy-mode = "rgmii";
> > +                ethernet = <&cpu_host_port>;
> > +                rx-internal-delay-ps = <2000>;
> > +                tx-internal-delay-ps = <2000>;
> > +
> > +                fixed-link {
> > +                    speed = <1000>;
> > +                    full-duplex;
> > +                    pause;
> > +                };
> > +            };
> > +        };
> > +    };
> > +...
> > +
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 7ae698067c41..8232da1b3951 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -17278,6 +17278,7 @@ M:    Jens Emil Schulz Østergaard <jensemil.schulzostergaard@microchip.com>
> >  M:   UNGLinuxDriver@microchip.com
> >  L:   netdev@vger.kernel.org
> >  S:   Maintained
> > +F:   Documentation/devicetree/bindings/net/dsa/microchip,lan96455s-switch.yaml
> >  F:   include/linux/dsa/lan9645x.h
> >  F:   net/dsa/tag_lan9645x.c
> > 
> > 
> > --
> > 2.52.0
> > 


^ permalink raw reply

* Re: [PATCH v6 13/21] drm: renesas: rz-du: mipi_dsi: Add RZ_MIPI_DSI_FEATURE_GPO0R feature
From: Tommaso Merciai @ 2026-04-08 14:58 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: tomm.merciai, geert, linux-renesas-soc, biju.das.jz,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Magnus Damm,
	Tomi Valkeinen, dri-devel, devicetree, linux-kernel, linux-clk
In-Reply-To: <20260408141719.GB1965119@killaraus.ideasonboard.com>

Hi Laurent,
Thanks for your comments.

On 4/8/26 16:17, Laurent Pinchart wrote:
> On Wed, Apr 08, 2026 at 04:12:22PM +0200, Tommaso Merciai wrote:
>> Hi Laurent,
>> Thanks for your review.
>>
>> On 4/8/26 14:31, Laurent Pinchart wrote:
>>> On Wed, Apr 08, 2026 at 12:36:58PM +0200, Tommaso Merciai wrote:
>>>> The MIPI DSI ip found in the RZ/G3E SoC select the video input clock
>>>> based on the DU instance actually connected using the GPO0R register.
>>>>
>>>> Add this feature to the driver using `RZ_MIPI_DSI_FEATURE_GPO0R`, update
>>>> the code accordingly to manage the vclk selection with the introduction
>>>> of `rzg2l_mipi_dsi_get_input_port()`.
>>>>
>>>> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
>>>> ---
>>>> v5->v6:
>>>>    - Moved rzg2l_mipi_dsi_link_write() into rzv2h_mipi_dsi_dphy_init()
>>>>      + comments from HW Manual.
>>>>
>>>> v4->v5:
>>>>    - No changes.
>>>>
>>>> v3->v4:
>>>>    - No changes.
>>>>
>>>> v2->v3:
>>>>    - No changes.
>>>>
>>>> v1->v2:
>>>>    - No changes.
>>>>
>>>>    .../gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c    | 71 +++++++++++++++++--
>>>>    .../drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h   |  3 +
>>>>    2 files changed, 68 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
>>>> index be6dbf19a24e..947c8e15fc4b 100644
>>>> --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
>>>> +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
>>>> @@ -37,7 +37,9 @@ MODULE_IMPORT_NS("RZV2H_CPG");
>>>>    
>>>>    #define RZG2L_DCS_BUF_SIZE	128 /* Maximum DCS buffer size in external memory. */
>>>>    
>>>> +#define RZ_MIPI_DSI_MAX_INPUT	2
>>>>    #define RZ_MIPI_DSI_FEATURE_16BPP	BIT(0)
>>>> +#define RZ_MIPI_DSI_FEATURE_GPO0R	BIT(1)
>>>>    
>>>>    struct rzg2l_mipi_dsi;
>>>>    
>>>> @@ -81,13 +83,14 @@ struct rzg2l_mipi_dsi {
>>>>    	struct drm_bridge bridge;
>>>>    	struct drm_bridge *next_bridge;
>>>>    
>>>> -	struct clk *vclk;
>>>> +	struct clk *vclk[RZ_MIPI_DSI_MAX_INPUT];
>>>>    	struct clk *lpclk;
>>>>    
>>>>    	enum mipi_dsi_pixel_format format;
>>>>    	unsigned int num_data_lanes;
>>>>    	unsigned int lanes;
>>>>    	unsigned long mode_flags;
>>>> +	u8 vclk_idx;
>>>>    
>>>>    	struct rzv2h_dsi_mode_calc mode_calc;
>>>>    
>>>> @@ -543,8 +546,8 @@ static int rzg2l_dphy_conf_clks(struct rzg2l_mipi_dsi *dsi, unsigned long mode_f
>>>>    	unsigned long vclk_rate;
>>>>    	unsigned int bpp;
>>>>    
>>>> -	clk_set_rate(dsi->vclk, mode_freq * KILO);
>>>> -	vclk_rate = clk_get_rate(dsi->vclk);
>>>> +	clk_set_rate(dsi->vclk[dsi->vclk_idx], mode_freq * KILO);
>>>> +	vclk_rate = clk_get_rate(dsi->vclk[dsi->vclk_idx]);
>>>>    	if (vclk_rate != mode_freq * KILO)
>>>>    		dev_dbg(dsi->dev, "Requested vclk rate %lu, actual %lu mismatch\n",
>>>>    			mode_freq * KILO, vclk_rate);
>>>> @@ -687,6 +690,19 @@ static int rzv2h_mipi_dsi_dphy_init(struct rzg2l_mipi_dsi *dsi,
>>>>    	rzg2l_mipi_dsi_phy_write(dsi, PLLCLKSET1R,
>>>>    				 FIELD_PREP(PLLCLKSET1R_PLL_K, dsi_parameters->k));
>>>>    
>>>> +	/*
>>>> +	 * From RZ/G3E HW manual (Rev.1.15) section 9.5.3 Operation,
>>>> +	 * 9.5.3.1 Power on Reset and Initial Settings for All Operations.
>>>> +	 * Figure 9.5-4 Power On/Off Sequence show that after writing to
>>>> +	 * GPO0R.VICH register we need to wait for more than 1 x tp before
>>>> +	 * writing to PLLENR.PLLEN.
>>>> +	 *
>>>> +	 * Note: GPO0R is a link register, not a PHY register. This setting
>>>> +	 * is specific to RZ/G3E.
>>>> +	 */
>>>> +	if (dsi->info->features & RZ_MIPI_DSI_FEATURE_GPO0R)
>>>> +		rzg2l_mipi_dsi_link_write(dsi, GPO0R, dsi->vclk_idx);
>>>> +
>>>>    	/*
>>>>    	 * From RZ/V2H HW manual (Rev.1.20) section 9.5.3 Operation,
>>>>    	 * (C) After write to D-PHY registers we need to wait for more than 1 x tp
>>>> @@ -1005,6 +1021,37 @@ static int rzg2l_mipi_dsi_stop_video(struct rzg2l_mipi_dsi *dsi)
>>>>    	return ret;
>>>>    }
>>>>    
>>>> +static int rzg2l_mipi_dsi_get_input_port(struct rzg2l_mipi_dsi *dsi)
>>>> +{
>>>> +	struct device_node *np = dsi->dev->of_node;
>>>> +	struct device_node *remote_ep, *ep_node;
>>>> +	struct of_endpoint ep;
>>>> +	bool ep_enabled;
>>>> +	int in_port;
>>>> +
>>>> +	/* DSI can have only one port enabled */
>>>
>>> Why is that ? The hardware supports dynamic input selection, why can't
>>> it be supported at runtime ?
>>
>> For runtime/dynamic you mean using DT overlay??
>> like, remove:
>>
>> Removing - DU0 --> DSI (input 0 | port@0 ) overlay and
>> install  - DU1 --> DSI (input 1 | port@1 ) overlay and
>> viceversa?
> 
> No, I mean configurable by userspace, with two CRTCs sharing one DSI
> encoder.

Sorry, question:
  - Is it possible to create CRTC from user space?

 From hardware point only one DSI input is selectable out of 2 LCDC's at 
a time.

References:
  - 9.5.2.2.3 9.5 MIPI DSI Interface (DSI)
    General Purpose Output 0 Register (DSI_LINK_GPO0R)

  - 9.5 MIPI DSI Interface (DSI)
    9.5.1.2 Block Diagram
    Figure 9.5-1 Video Input Interface

Kind Regards,
Tommaso

> 
>>>> +	for_each_endpoint_of_node(np, ep_node) {
>>>> +		of_graph_parse_endpoint(ep_node, &ep);
>>>> +		if (ep.port >= RZ_MIPI_DSI_MAX_INPUT)
>>>> +			break;
>>>> +
>>>> +		remote_ep = of_graph_get_remote_endpoint(ep_node);
>>>> +		ep_enabled = of_device_is_available(remote_ep);
>>>> +		of_node_put(remote_ep);
>>>> +
>>>> +		if (ep_enabled) {
>>>> +			in_port = ep.port;
>>>> +			break;
>>>> +		}
>>>> +	}
>>>> +
>>>> +	if (!ep_enabled)
>>>> +		return -EINVAL;
>>>> +
>>>> +	dev_dbg(dsi->dev, "input port@%d\n", in_port);
>>>> +	return in_port;
>>>> +}
>>>> +
>>>>    /* -----------------------------------------------------------------------------
>>>>     * Bridge
>>>>     */
>>>> @@ -1425,9 +1472,21 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev)
>>>>    	if (IS_ERR(dsi->mmio))
>>>>    		return PTR_ERR(dsi->mmio);
>>>>    
>>>> -	dsi->vclk = devm_clk_get(dsi->dev, "vclk");
>>>> -	if (IS_ERR(dsi->vclk))
>>>> -		return PTR_ERR(dsi->vclk);
>>>> +	dsi->vclk[0] = devm_clk_get(dsi->dev, "vclk");
>>>> +		if (IS_ERR(dsi->vclk[0]))
>>>> +			return PTR_ERR(dsi->vclk[0]);
>>>> +
>>>> +	if (dsi->info->features & RZ_MIPI_DSI_FEATURE_GPO0R) {
>>>> +		dsi->vclk[1] = devm_clk_get(dsi->dev, "vclk2");
>>>> +		if (IS_ERR(dsi->vclk[1]))
>>>> +			return PTR_ERR(dsi->vclk[1]);
>>>> +
>>>> +		ret = rzg2l_mipi_dsi_get_input_port(dsi);
>>>> +		if (ret < 0)
>>>> +			return dev_err_probe(dsi->dev, -EINVAL,
>>>> +					     "No available input port\n");
>>>> +		dsi->vclk_idx = ret;
>>>> +	}
>>>>    
>>>>    	dsi->lpclk = devm_clk_get(dsi->dev, "lpclk");
>>>>    	if (IS_ERR(dsi->lpclk))
>>>> diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
>>>> index 2bef20566648..cee2e0bc5dc5 100644
>>>> --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
>>>> +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
>>>> @@ -83,6 +83,9 @@
>>>>    #define LINKSR_SQCHRUN1			BIT(4)
>>>>    #define LINKSR_SQCHRUN0			BIT(0)
>>>>    
>>>> +/* RZ/G3E General Purpose Output 0 Register */
>>>> +#define GPO0R				0xc0
>>>> +
>>>>    /* Tx Set Register */
>>>>    #define TXSETR				0x100
>>>>    #define TXSETR_NUMLANECAP		(0x3 << 16)
> 


^ permalink raw reply

* Re: [PATCH net-next v2 4/9] net: dsa: lan9645x: add basic dsa driver for LAN9645X
From: Jens Emil Schulz Ostergaard @ 2026-04-08 14:57 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Jakub Kicinski, UNGLinuxDriver, andrew, davem, edumazet, pabeni,
	horms, robh, krzk+dt, conor+dt, woojung.huh, linux,
	Steen.Hegelund, daniel.machon, linux-kernel, netdev, devicetree
In-Reply-To: <20260407091217.rrwzho3lcmfip3y5@skbuf>

On Tue, 2026-04-07 at 12:12 +0300, Vladimir Oltean wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Wed, Apr 01, 2026 at 01:46:19PM +0200, Jens Emil Schulz Ostergaard wrote:
> > On Sun, 2026-03-29 at 12:56 -0700, Jakub Kicinski wrote:
> > > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > > 
> > > This is an AI-generated review of your patch. The human sending this
> > > email has considered the AI review valid, or at least plausible.
> > > ---
> > > Subject: net: dsa: lan9645x: add basic dsa driver for LAN9645X
> > > 
> > > This commit adds a basic DSA driver for the Microchip LAN9645X switch. It
> > > includes initialization, port module setup for NPI, CPU, and front ports,
> > > and phylink integration for MAC side configuration.
> > > 
> > > diff --git a/drivers/net/dsa/microchip/lan9645x/lan9645x_npi.c b/drivers/net/dsa/microchip/lan9645x/lan9645x_npi.c
> > > --- a/drivers/net/dsa/microchip/lan9645x/lan9645x_npi.c
> > > +++ b/drivers/net/dsa/microchip/lan9645x/lan9645x_npi.c
> > > [ ... ]
> > > > +static void disable_conduit_ipv6(struct lan9645x *lan9645x,
> > > > +                              struct net_device *conduit)
> > > > +{
> > > > +     struct inet6_dev *dev_v6;
> > > > +
> > > > +     if (!conduit)
> > > > +             return;
> > > > +
> > > > +     /* IPv6 on the conduit will generate frames bypassing our tag driver, so
> > > > +      * they lack an IFH. This will be garbage in garbage out and we want to
> > > > +      * avoid this.
> > > > +      */
> > > > +     rtnl_lock();
> > > > +     dev_v6 = __in6_dev_get(conduit);
> > > > +     if (dev_v6) {
> > > > +             WRITE_ONCE(dev_v6->cnf.disable_ipv6, 1);
> > > > +             dev_warn(lan9645x->dev, "Disabled IPv6 on conduit device: %s\n",
> > > > +                      netdev_name(conduit));
> > > > +     }
> > > > +     rtnl_lock();
> > > > +}
> > > 
> > > Does directly modifying dev_v6->cnf.disable_ipv6 bypass the proper sysctl
> > > teardown path (addrconf_disable_ipv6) and leave the IPv6 stack in an
> > > inconsistent state on the conduit device by failing to clean up routes,
> > > addresses, and MLD memberships?
> > > 
> > > Is it a layering violation for a switch driver to alter the networking
> > > configuration of an external upper device, especially since this change
> > > isn't reverted during driver unbind?
> > 
> > Yes this will bypass the sysctl teardown path. I can change this to instead
> > read disable_ipv6 state and warn the user that their device is misconfigured.
> 
> I don't want to have to deal with a DSA driver altering the conduit
> configuration outside of the DSA core. NACK to any attempts of trying
> this.
> 
> Define "garbage in, garbage out" for your case. The packets are sent to
> random ports? Normally, switches are configured by their drivers to drop
> those packets that don't contain DSA tags. You can also do that, by
> setting up the switch to require an injection prefix.
> 
> > > [ ... ]
> > > > +     /* Configure IFH prefix mode for NPI port. */
> > > > +     lan_rmw(SYS_PORT_MODE_INCL_XTR_HDR_SET(LAN9645X_TAG_PREFIX_LONG) |
> > > > +             SYS_PORT_MODE_INCL_INJ_HDR_SET(LAN9645X_TAG_PREFIX_NONE),
> > > > +             SYS_PORT_MODE_INCL_XTR_HDR |
> > > > +             SYS_PORT_MODE_INCL_INJ_HDR,
> > > > +             lan9645x,
> > > > +             SYS_PORT_MODE(p->chip_port));
> > > 
> > > Setting LAN9645X_TAG_PREFIX_NONE means the hardware interprets the first
> > > bytes of any frame received from the host as an IFH command structure.
> > > 
> > > Does this allow a local user to transmit crafted frames (for example, via
> > > raw sockets or standard protocols) whose MAC address bytes map to malicious
> > > IFH commands, thereby bypassing VLAN isolation or flooding the switch?
> > > 
> > > Should the hardware be configured to require a strict prefix, such as
> > > LAN9645X_TAG_PREFIX_LONG, for injected frames to prevent this?
> > 
> > A prefix offers no protection against the described scenario. The current
> > configuration is correct. If a prefix is configured frames MUST contain the
> > prefix. With the conduit exposed in userspace this is not something we can
> > guarantee.
> 
> The short prefix prevents user space from sending frames by mistake
> which will reach the wire (daemons attaching to all interfaces, like for DHCP).
> It still allows user space to intentionally inject frames into the
> switch (for example from XDP on the conduit).
> 
> I recommend you go for the short prefix and drop the conduit alterations.
> 


By garbage in, garbage out I mean frames will be interpreted as having
an IFH, and may be sent to random ports depending the bytes in the
frame.

Unfortunately, configuring an injection prefix is not a good solution.
If an injection prefix is configured frames MUST contain this prefix. If
frames are received which do not contain the prefix they will corrupt
the queue system leaving the port unusable.

Since the driver does not have control over frames sent to the NPI port,
an injection prefix configuration is highly undesirable.

I will remove the conduit alterations.


> > > diff --git a/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c b/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
> > > --- a/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
> > > +++ b/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
> > > [ ... ]
> > > > +static int lan9645x_setup(struct dsa_switch *ds)
> > > > +{
> > > > +     struct lan9645x *lan9645x = ds->priv;
> > > > +     struct device *dev = lan9645x->dev;
> > > > +     u32 all_phys_ports;
> > > > +     int err;
> > > > +
> > > > +     lan9645x->num_phys_ports = ds->num_ports;
> > > > +     all_phys_ports = GENMASK(lan9645x->num_phys_ports - 1, 0);
> > > > +
> > > > +     err = lan9645x_reset_switch(lan9645x);
> > > > +     if (err)
> > > > +             return err;
> > > > +
> > > > +     lan9645x->ports = devm_kcalloc(lan9645x->dev, lan9645x->num_phys_ports,
> > > > +                                    sizeof(struct lan9645x_port *),
> > > > +                                    GFP_KERNEL);
> > > 
> > > Since the DSA .setup callback can be invoked multiple times during the
> > > platform device's lifetime (for example, when the DSA master interface is
> > > unbound and bound again), does using devm_kcalloc here cause a memory leak?
> > > Should these allocations be moved to .probe or managed with kcalloc and
> > > freed in .teardown?
> > > 
> > 
> > Hmm I do not think this is right? I think dsa_tree_teardown is called from
> > dsa_switch_remove which is called by the switch drivers .remove.
> > 
> > So I do not think you can get multiple setup/teardown cycles during the device
> > lifetime?
> > 
> > As far as I can tell both felix and ksz use device managed allocations in their
> > setup callback.
> 
> It's valid feedback in general. In a multi-switch tree, ds->ops->setup()
> is called when the tree is complete, and ds->ops->teardown() when the
> first switch disappears. If there are 2 switches and you unbind and
> rebind the driver from A, then switch B will see a ds->ops->teardown()
> call followed by ds->ops->setup().
> 
> In your case, since the switch doesn't support cascading, it probably
> doesn't matter. But the LLM doesn't have the context to know that.
> 


OK, I was not aware of this. I tried following the callstack and it did not seem
like the described scenario was possible. If device managed allocations are fine
when you do not support cascading, I would prefer to keep them.

> > > [ ... ]
> > > > +     /* Set all the entries to obey VLAN. */
> > > > +     for (int i = 0; i < PGID_ENTRIES; ++i)
> > > > +             lan_wr(ANA_PGID_CFG_OBEY_VLAN_SET(1),
> > > > +                    lan9645x, ANA_PGID_CFG(i));
> > > 
> > > PGID_ENTRIES is defined as 89, so this loop initializes indices 0 through
> > > 88. Since the CPU port is index 9, its source PGID is PGID_SRC + CPU_PORT
> > > (80 + 9 = 89).
> > > 
> > > Is index 89 left uninitialized, breaking the OBEY_VLAN rule and allowing
> > > CPU-injected frames to leak across VLAN boundaries?
> > > 
> > 
> > No I this misunderstands OBEY_VLAN. When set the vlan table can control
> > whether cpu copy from the pgid table is enabled. It makes no sense for PGID 89.
> 
> Explain that in a comment.
> 

I will add a comment about this.

> > > [ ... ]
> > > > +     /* Multicast to all front ports */
> > > > +     lan_wr(all_phys_ports, lan9645x, ANA_PGID(PGID_MC));
> > > > +
> > > > +     /* IP multicast to all front ports */
> > > > +     lan_wr(all_phys_ports, lan9645x, ANA_PGID(PGID_MCIPV4));
> > > > +     lan_wr(all_phys_ports, lan9645x, ANA_PGID(PGID_MCIPV6));
> > > > +
> > > > +     /* Unicast to all front ports */
> > > > +     lan_wr(all_phys_ports, lan9645x, ANA_PGID(PGID_UC));
> > > > +
> > > > +     /* Broadcast to all ports */
> > > > +     lan_wr(BIT(CPU_PORT) | all_phys_ports, lan9645x, ANA_PGID(PGID_BC));
> > > 
> > > PGID_BC includes BIT(CPU_PORT) and all_phys_ports (which includes the NPI
> > > port). Will this forward broadcast frames to both the CPU extraction queue
> > > and the NPI port's normal egress queue, causing duplicate frames for the host?
> > > 
> > > Conversely, the multicast masks and PGID_UC exclude BIT(CPU_PORT). Does
> > > this cause them to bypass the CPU extraction queue entirely, thereby
> > > lacking the LONG extraction prefix and breaking the host's DSA tagger parsing?
> > > 
> > 
> > No this is not how it works. Generally when you configure the CPU port to use
> > an NPI port, the hardware manages this internally. You do you have to start
> > using the npi port number all of a sudden.
> 
> The comment is fair though. Why would you set all_phys_ports to
> GENMASK(lan9645x->num_phys_ports - 1, 0) when you can compute the mask
> of user ports which are enabled? It seems sloppy at best, and also
> contradictory (comments say "all front ports", but code includes the NPI
> port in this mask).
> 

I will use dsa_user_ports(ds) as the base mask for the flood masks.

> > > [ ... ]
> > > > +int lan9645x_port_setup(struct dsa_switch *ds, int port)
> > > > +{
> > > > +     struct dsa_port *dp = dsa_to_port(ds, port);
> > > > +     struct lan9645x *lan9645x = ds->priv;
> > > > +     struct lan9645x_port *p;
> > > > +
> > > > +     p = lan9645x_to_port(lan9645x, port);
> > > > +
> > > > +     if (dp->dn) {
> > > > +             p->rx_internal_delay =
> > > > +                     of_property_present(dp->dn, "rx-internal-delay-ps");
> > > > +             p->tx_internal_delay =
> > > > +                     of_property_present(dp->dn, "tx-internal-delay-ps");
> > > > +     }
> > > 
> > > These are standard integer properties specifying delays in picoseconds. If
> > > a user explicitly disables the delay via devicetree using a value of 0,
> > > will of_property_present evaluate to true and enable the hardware delay
> > > anyway? Should of_property_read_u32 be used instead to check the value?
> > 
> > A value of 0 is not allowed per the bindings. The bindings enforce that if this
> > is present the value must be 2000.
> 
> Bindings may change. Please use of_property_read_u32().
> 


I will switch to of_property_read_u32.

^ permalink raw reply

* Re: [PATCH v5 2/2] dt-bindings: pinctrl: pinctrl-max77620: convert to DT schema
From: Rob Herring @ 2026-04-08 14:52 UTC (permalink / raw)
  To: Svyatoslav Ryhel
  Cc: Linus Walleij, Krzysztof Kozlowski, Conor Dooley, Liam Girdwood,
	Mark Brown, linux-gpio, devicetree, linux-kernel
In-Reply-To: <20260406075114.25672-3-clamor95@gmail.com>

On Mon, Apr 6, 2026 at 2:51 AM Svyatoslav Ryhel <clamor95@gmail.com> wrote:
>
> Convert pinctrl-max77620 devicetree bindings for the MAX77620 PMIC from
> TXT to YAML format. This patch does not change any functionality; the
> bindings remain the same.
>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> ---
>  .../pinctrl/maxim,max77620-pinctrl.yaml       |  98 ++++++++++++++
>  .../bindings/pinctrl/pinctrl-max77620.txt     | 127 ------------------
>  2 files changed, 98 insertions(+), 127 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/maxim,max77620-pinctrl.yaml
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-max77620.txt

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>

This needs to go into 7.1 as the MFD part was already applied.

^ permalink raw reply

* Re: [PATCH v2 0/7] thermal: samsung: Add support for Google GS101 TMU
From: Alexey Klimov @ 2026-04-08 14:49 UTC (permalink / raw)
  To: Tudor Ambarus
  Cc: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Krzysztof Kozlowski, Alim Akhtar, Bartlomiej Zolnierkiewicz,
	Kees Cook, Gustavo A. R. Silva, Peter Griffin, André Draszik,
	willmcvicker, jyescas, shin.son, linux-samsung-soc, linux-kernel,
	linux-pm, devicetree, linux-arm-kernel, linux-hardening
In-Reply-To: <20260119-acpm-tmu-v2-0-e02a834f04c6@linaro.org>

On Mon Jan 19, 2026 at 12:08 PM GMT, Tudor Ambarus wrote:
> Add support for the Thermal Management Unit (TMU) on the Google GS101
> SoC.
>
> The GS101 TMU implementation utilizes a hybrid architecture where
> management is shared between the kernel and the Alive Clock and
> Power Manager (ACPM) firmware.

Do you plan to update or work on this series? If, by some reason,
this series is postphoned I can rebase it and re-send, for example.
IIRC it needs a clean rebase as a minimial change.

I am constructing some code on top of it, so it will be nice to have
newer version that can be (re-)tested for Exynos850.

Thanks,
Alexey

[...]

^ permalink raw reply

* Re: [PATCH v6 10/21] dt-bindings: display: renesas,rzg2l-du: Add support for RZ/G3E SoC
From: Tommaso Merciai @ 2026-04-08 14:44 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: tomm.merciai, geert, linux-renesas-soc, biju.das.jz,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Magnus Damm,
	Tomi Valkeinen, dri-devel, devicetree, linux-kernel, linux-clk
In-Reply-To: <20260408141638.GA1965119@killaraus.ideasonboard.com>

Hi Laurent,
Thanks for your comment.

On 4/8/26 16:16, Laurent Pinchart wrote:
> On Wed, Apr 08, 2026 at 04:02:14PM +0200, Tommaso Merciai wrote:
>> Hi Laurent,
>> Thanks for your review.
>>
>> On 4/8/26 14:24, Laurent Pinchart wrote:
>>> On Wed, Apr 08, 2026 at 12:36:55PM +0200, Tommaso Merciai wrote:
>>>> The RZ/G3E SoC has 2 LCD controllers (LCDC), each containing a Frame
>>>> Compression Processor (FCPVD), a Video Signal Processor (VSPD), and a
>>>> Display Unit (DU).
>>>>
>>>>    - LCDC0 supports DSI and LVDS (single or dual-channel) outputs.
>>>>    - LCDC1 supports DSI, LVDS (single-channel), and RGB outputs.
>>>>
>>>> Add a new SoC-specific compatible string 'renesas,r9a09g047-du'.
>>>>
>>>> Extend patternProperties from "^port@[0-1]$" to "^port@[0-3]$" to
>>>> allow up to four output ports, and explicitly disable port@2 and port@3
>>>> for existing SoCs that do not expose them.
>>>>
>>>> Describe the four output ports of the RZ/G3E DU:
>>>>
>>>>    - port@0: DSI (available on both LCDC instances)
>>>>    - port@1: DPAD / parallel RGB (LCDC1 only)
>>>>    - port@2: LVDS channel 0 (LCDC0 only)
>>>>    - port@3: LVDS channel 1 (available on both LCDC instances)
>>>>
>>>> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
>>>> ---
>>>> v5->v6:
>>>>    - Extend patternProperties from "^port@[0-1]$" to "^port@[0-3]$" and
>>>>      explicitly disable port@2 and port@3 for existing SoCs that do not expose
>>>>      them.
>>>>    - Reworked ports numbering + improved/fixed ports descriptions in the
>>>>      bindings documentation.
>>>>    - Improved commit body.
>>>>
>>>> v4->v5:
>>>>    - Dropped renesas,id property and updated bindings
>>>>      accordingly.
>>>>
>>>> v2->v3:
>>>>    - No changes.
>>>>
>>>> v2->v3:
>>>>    - No changes.
>>>>
>>>> v1->v2:
>>>>    - Use single compatible string instead of multiple compatible strings
>>>>      for the two DU instances, leveraging a 'renesas,id' property to
>>>>      differentiate between DU0 and DU1.
>>>>    - Updated commit message accordingly.
>>>>
>>>>    .../bindings/display/renesas,rzg2l-du.yaml    | 30 ++++++++++++++++++-
>>>>    1 file changed, 29 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
>>>> index 5add3b832eab..32da0b5ec88c 100644
>>>> --- a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
>>>> +++ b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
>>>> @@ -20,6 +20,7 @@ properties:
>>>>          - enum:
>>>>              - renesas,r9a07g043u-du # RZ/G2UL
>>>>              - renesas,r9a07g044-du # RZ/G2{L,LC}
>>>> +          - renesas,r9a09g047-du # RZ/G3E
>>>>              - renesas,r9a09g057-du # RZ/V2H(P)
>>>>          - items:
>>>>              - enum:
>>>> @@ -61,7 +62,7 @@ properties:
>>>>          model-dependent. Each port shall have a single endpoint.
>>>>    
>>>>        patternProperties:
>>>> -      "^port@[0-1]$":
>>>> +      "^port@[0-3]$":
>>>>            $ref: /schemas/graph.yaml#/properties/port
>>>>            unevaluatedProperties: false
>>>>    
>>>> @@ -103,6 +104,8 @@ allOf:
>>>>                port@0:
>>>>                  description: DPI
>>>>                port@1: false
>>>> +            port@2: false
>>>> +            port@3: false
>>>>    
>>>>              required:
>>>>                - port@0
>>>> @@ -119,6 +122,8 @@ allOf:
>>>>                  description: DSI
>>>>                port@1:
>>>>                  description: DPI
>>>> +            port@2: false
>>>> +            port@3: false
>>>>    
>>>>              required:
>>>>                - port@0
>>>> @@ -135,9 +140,32 @@ allOf:
>>>>                port@0:
>>>>                  description: DSI
>>>>                port@1: false
>>>> +            port@2: false
>>>> +            port@3: false
>>>>    
>>>>              required:
>>>>                - port@0
>>>> +  - if:
>>>> +      properties:
>>>> +        compatible:
>>>> +          contains:
>>>> +            const: renesas,r9a09g047-du
>>>> +    then:
>>>> +      properties:
>>>> +        ports:
>>>> +          properties:
>>>> +            port@0:
>>>> +              description: DSI
>>>> +            port@1:
>>>> +              description: DPAD
>>>> +            port@2:
>>>> +              description: LVDS, Channel 0
>>>> +            port@3:
>>>> +              description: LVDS, Channel 1
>>>> +
>>>> +          required:
>>>> +            - port@0
>>>> +            - port@3
>>>
>>> Why are ports 1 and 2 not required ?
>>
>> About this we had a similar discussion on v5[0]
>> We are using the same compatible and:
>>
>> - LCDC0 supports DSI and LVDS (single or dual-channel) outputs.
>> |
>> --> then has:
>> 	port@0
>> 	port@2
>> 	port@3
>> 	
>>
>>    - LCDC1 supports DSI, LVDS (single-channel), and RGB outputs.
>> |
>> --> then has:
>> 	port@0
>> 	port@1
>> 	port@3
> 
> Ah yes, I forget there are two LCDC instances with different output
> configurations.
> 
> Something still looks a bit weird to me though. For LCDC1, which
> supports a single LVDS channel, you use the port described as the second
> LVDS channel. Is there a reason not to use port@2 ?


9.11 Low Voltage Differential Signaling (LVDS)
9.11.1.2 Block Diagram
Figure 9.11-1 shows a block diagram of LVDS.

LCDC1 is connected to LVDS, Channel 1
For this reason I'm using port@3.

Kind Regards,
Tommaso

> 
>> Then port@1 is required for DU1 but not for DU0.
>> Same port@2 is required for DU0 but not for DU1.
>>
>> [0] https://patchwork.kernel.org/project/linux-renesas-soc/patch/ca022fdbba5236c36e0cb3095db4c31e8e0cb1b8.1770996493.git.tommaso.merciai.xr@bp.renesas.com/
>>
>>>>
>>>>    examples:
>>>>      # RZ/G2L DU
> 


^ permalink raw reply

* Re: [PATCH 06/13] clk: amlogic: Add noglitch clock driver
From: Chuan Liu @ 2026-04-08 14:44 UTC (permalink / raw)
  To: Martin Blumenstingl
  Cc: Neil Armstrong, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-amlogic, linux-clk,
	devicetree, linux-kernel
In-Reply-To: <CAFBinCBXFxefUkNj3sqUdnTz7vf72jV_FkCP6gd2veTtLHWnBg@mail.gmail.com>

Hi Martin,
Thanks for review.

On 2/10/2026 5:51 AM, Martin Blumenstingl wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi Chuan Liu,
> 
> On Mon, Feb 9, 2026 at 6:49 AM Chuan Liu via B4 Relay
> <devnull+chuan.liu.amlogic.com@kernel.org> wrote:
> [...]
>> + * To prevent glitches from propagating to clk_out and affecting the normal
>> + * operation of glitch-sensitive modules, the no-glitch clock must be configured
>> + * following the specified sequence:
>> + *   - When the clock gate is disabled: configure it as a normal composite clock
>> + *     (any glitches generated will be blocked by the gate and will not
>> + *     propagate to clk_out).
> This part is easy and makes sense.
> 
>> + *   - When the clock gate is enabled: configure it according to the following
>> + *     sequence to suppress glitches:
>> + *       - Configure and enable the idle composite clock path of the
>> + *         noglitch_mux with the target frequency/parent clock.
>> + *       - Switch the noglitch_mux to the channel prepared in the previous step.
>> + *       - Disable the clock of the original noglitch_mux channel.
>> + */
>  From a previous discussion it seems that in reality things need to be
> handled more carefully as you previously mentioned that
> CLK_SET_RATE_GATE is not good enough (the description above is what
> CLK_SET_RATE_GATE already achieves).
> For the more careful handling Jerome suggested using the clock
> protection logic: [0]
> You wanted to try it out at some point: [1]
> Is the verdict that Jerome's suggestion did not work? Can you please
> share some details as to why it doesn't work.
> 

In the actual use case, this switching operation completes within the 
nanosecond range (with a minimum clock frequency of 24 MHz in typical 
scenarios), which is why no issues were observed on our previous SoCs.

Thank you for the reminder, to be on the safe side, I will introduce 
some explicit hardware delays in the future revision.

> 
> Best regards,
> Martin
> 
> 
> [0] https://lore.kernel.org/linux-amlogic/1j1pnp5sg7.fsf@starbuckisacylon.baylibre.com/
> [1] https://lore.kernel.org/linux-amlogic/1639bb9d-9cb7-409f-bbf8-bfe4a5d1b8bc@amlogic.com/

-- 
Best regards,
Chuan


^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: pci: sophgo: Add dma-coherent property for SG2042
From: Rob Herring (Arm) @ 2026-04-08 14:41 UTC (permalink / raw)
  To: Han Gao
  Cc: Inochi Amaoto, Conor Dooley, Bjorn Helgaas, devicetree, Albert Ou,
	linux-riscv, Lorenzo Pieralisi, Alexandre Ghiti,
	Manivannan Sadhasivam, Palmer Dabbelt, Krzysztof Wilczyński,
	Chen Wang, Zixian Zeng, Krzysztof Kozlowski, Han Gao,
	linux-kernel, sophgo, linux-pci, Paul Walmsley
In-Reply-To: <20260331171248.973014-2-gaohan@iscas.ac.cn>


On Wed, 01 Apr 2026 01:12:47 +0800, Han Gao wrote:
> Add dma-coherent as an allowed property in the SG2042 PCIe host
> controller binding. SG2042's PCIe root complexes are cache-coherent
> with the CPU.
> 
> Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
> ---
>  .../devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml       | 3 +++
>  1 file changed, 3 insertions(+)
> 

Acked-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply

* Re: [PATCH v3] dt-bindings: timer: Add SiFive CLINT2
From: Charles Perry @ 2026-04-08 14:40 UTC (permalink / raw)
  To: Nick Hu
  Cc: Charles Perry, Daniel Lezcano, Thomas Gleixner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Paul Walmsley, Samuel Holland,
	Palmer Dabbelt, Anup Patel, linux-kernel, devicetree, linux-riscv
In-Reply-To: <CAKddAkCZXmw95XN6ypd_i=JqkMUooD=riTisHUMrY8Kqkebbqw@mail.gmail.com>

On Wed, Apr 08, 2026 at 02:15:19PM +0800, Nick Hu wrote:
> On Fri, Mar 27, 2026 at 4:56 AM Charles Perry
> <charles.perry@microchip.com> wrote:
> >
> > On Fri, Mar 21, 2025 at 04:35:06PM +0800, Nick Hu wrote:
> > > Add compatible string and property for the SiFive CLINT v2. The SiFive
> > > CLINT v2 is incompatible with the SiFive CLINT v0 due to differences
> > > in their control methods.
> >
> > Hello Nick,
> >
> > Can you help me understand what is this different control method? I've
> > found that both OpenSBI [1] and U-Boot [2] use the same match data in their
> > clint driver which would indicate that they are compatible.
> >
> Sorry for the late reply.

Hello Nick, no worries.

> Unlike v0, v2 requires a write to the mtime register to kick the timer.

A kick once at the beginning or every time a machine timer interrupt fires?

> 
> > Also, do you know if there's an easy way to tell if a sifive clint is a v0
> > or v2?
> >
> sifive,clint2 introduces additional MMIO registers

Is that the high resolution timers (HRT) mentionned in the description?

And last question, would you happen to know if sifive made a clint v1 that
does NOT require the mtime kick but does have the HRT?

I'm trying to figure out what should be the compatible for PIC64-HPSC.
Some code from a repository called "FSFM" used "sifive,clint1" for the
compatible. I'm wondering if I should add the clint v1 to this file.

Thanks,
Charles


^ permalink raw reply

* Re: [PATCH v6 1/4] dt-bindings: i2c: qcom,i2c-geni: Document multi-owner controller support
From: Rob Herring (Arm) @ 2026-04-08 14:39 UTC (permalink / raw)
  To: Mukesh Kumar Savaliya
  Cc: vkoul, linux-i2c, andersson, linux-kernel, krzysztof.kozlowski,
	bartosz.golaszewski, dmaengine, Frank.Li, andi.shyti, devicetree,
	bjorn.andersson, konrad.dybcio, viken.dadhaniya, agross,
	quic_jseerapu, conor+dt, konradybcio, linux-arm-msm, krzk+dt,
	linmq006, dmitry.baryshkov
In-Reply-To: <20260331114742.2896317-2-mukesh.savaliya@oss.qualcomm.com>


On Tue, 31 Mar 2026 17:17:39 +0530, Mukesh Kumar Savaliya wrote:
> Document a DeviceTree property to describe QUP-based I2C controllers that
> are shared with one or more other system processors.
> 
> On some Qualcomm platforms, a QUP-based I2C controller may be accessed by
> multiple system processors (for example, APPS and DSP). In such
> configurations, the operating system must not assume exclusive ownership
> of the controller or its associated hardware resources.
> 
> The new qcom,qup-multi-owner property indicates that the controller is
> externally shared and that the operating system must avoid operations
> which rely on sole control of the hardware.
> 
> Signed-off-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
> ---
>  .../devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml        | 7 +++++++
>  1 file changed, 7 insertions(+)
> 

Acked-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply

* Re: [PATCH 01/13] dt-bindings: clock: Add Amlogic A9 standardized model clock control units
From: Chuan Liu @ 2026-04-08 14:37 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Neil Armstrong, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
	Martin Blumenstingl
In-Reply-To: <10caac08-1a1d-4fe9-8df8-e0b75c532e8f@kernel.org>

Hi Krzysztof,
Thanks for review.

On 2/9/2026 9:14 PM, Krzysztof Kozlowski wrote:
> [ EXTERNAL EMAIL ]
> 
> On 09/02/2026 06:48, Chuan Liu via B4 Relay wrote:
>> From: Chuan Liu <chuan.liu@amlogic.com>
>>
>> Add dt-binding documentation for standardized model clock control units
>> in A9 SoC family.
>>
>> Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
>> ---
>>   .../bindings/clock/amlogic,a9-model-ccu.yaml       | 435 +++++++++++++++++++++
>>   1 file changed, 435 insertions(+)
> 
> Brief review, you still have to read basic guidelines to not repeat the
> basic mistakes.
> 
>>
>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,a9-model-ccu.yaml b/Documentation/devicetree/bindings/clock/amlogic,a9-model-ccu.yaml
>> new file mode 100644
>> index 000000000000..56c5cbe1b246
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/amlogic,a9-model-ccu.yaml
>> @@ -0,0 +1,435 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +# Copyright (C) 2026 Amlogic, Inc. All rights reserved
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/amlogic,a9-model-ccu.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Amlogic A9 Family Standardized Model Clock Control Unit
>> +
>> +maintainers:
>> +  - Chuan Liu <chuan.liu@amlogic.com>
>> +
>> +description:
>> +  The clock tree within the A9 is composed of numerous instances of these
>> +  standardized model CCU (Clock Control Units).
>> +
>> +properties:
>> +  compatible:
>> +    oneOf:
>> +      - items:
> 
> Drop
> 
>> +          - const: amlogic,a9-composite-ccu
>> +        description: Supports clock source selection, frequency division, and
>> +                     clock gating.
> 
> This is just one big enum. You can add comments if you insist...

Thanks for pointing out. I'll refer to this approach for future comments 
if necessary:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/clock/samsung,exynos5433-clock.yaml?h=v7.0-rc7#n26

> 
> 
>> +      - items:
>> +          - const: amlogic,a9-composite-ccu-mult
>> +        description: Some modules have multiple input clocks and contain
>> +                     multiple composite-ccus internally.
>> +      - items:
>> +          - const: amlogic,a9-noglitch-ccu
>> +        description: Provides the same functionality as composite-ccu but
>> +                     includes glitch suppression during frequency transitions.
>> +      - items:
>> +          - const: amlogic,a9-noglitch-ccu-mult
>> +        description: Some modules have multiple input clocks and contain
>> +                     multiple noglitch-ccus internally.
>> +      - items:
>> +          - const: amlogic,a9-sysbus-ccu
>> +        description: Consists of multiple gating arrays, commonly used for
>> +                     Amlogic's sys_clk and axi_clk.
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    minItems: 1
>> +    maxItems: 16
>> +
>> +  clock-names:
>> +    minItems: 1
>> +    maxItems: 16
>> +
>> +  clock-output-names:
>> +    minItems: 1
>> +    # The sysbus-ccu of A9 supports up to 128 gates
>> +    maxItems: 128
>> +
>> +  '#clock-cells':
>> +    description:
>> +      The clock controller of a module may contain one or more CCU(s). When a
>> +      clock controller has multiple CCUs, an index is required to specify a
>> +      particular CCU within the clock controller.
> 
> Drop
> 
>> +    oneOf:
>> +      - const: 0
>> +        description: Single clock output, no specifier needed
>> +      - const: 1
>> +        description: Multiple clocks, index selects specific output
> 
> Drop all descriptions. That's enum. Do not explain usu how DT works.
> 
>> +
>> +  amlogic,clock-max-frequency:
> 
> Drop property. So many wrong things here... First, start from basic
> guidelines like talks or docs in kernel and understand the suffixes.
> 
> Second not a DT property.
> 

Thanks for pointing out. Martin also helped me explain the reasons in 
detail. Thanks again.

>> +    description: |
>> +      Each clock's maximum output frequency is constrained during hardware
>> +      design to ensure proper timing requirements for the clock network. If the
>> +      clock frequency configured exceeds this design limit, it can lead to
>> +      abnormal behavior in modules relying on that clock and may even cause
>> +      cross-talk that affects other modules.
>> +
>> +      In the driver, this property is parsed, and interface functions from the
> 
> Why would we care about driver?
> 
> This is binding, we talk about hardware.
> 
> 
>> +      CCF are called to enforce the clock's maximum frequency, preventing
>> +      potential issues caused by excessive clock frequency configurations.
>> +    $ref: /schemas/types.yaml#/definitions/uint32-array
>> +
>> +  amlogic,reg-layout:
> 
> No, drop. Compatible defines it.
> 
>> +    description:
>> +      These standardized model CCUs require register configuration for their
>> +      clock functions. This property node describes the register layout
>> +      parameters for each model's CCU.
>> +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
>> +
>> +allOf:

[...]

>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: amlogic,a9-noglitch-ccu-mult
>> +    then:
>> +      properties:
>> +        clocks:
>> +          minItems: 1
> 
> Why?

noglitch-ccu processes the input clock and outputs it, so it needs to 
have at least one input clock.

> 
>> +          items:
>> +            - description: input clock source 0
>> +            - description: input clock source 1 (optional)
> 
> Drop optional. Don't repeat constraints in free form text.
> 
>> +            - description: input clock source 2 (optional)
>> +            - description: input clock source 3 (optional)
>> +            - description: input clock source 4 (optional)
>> +            - description: input clock source 5 (optional)
>> +            - description: input clock source 6 (optional)
>> +            - description: input clock source 7 (optional)
>> +        clock-names:
>> +          minItems: 1
>> +          items:
>> +            - const: clkin0
>> +            - const: clkin1
>> +            - const: clkin2
>> +            - const: clkin3
>> +            - const: clkin4
>> +            - const: clkin5
>> +            - const: clkin6
>> +            - const: clkin7
>> +        amlogic,reg-layout:
>> +          description: |
>> +            composite-ccu contains one register layout parameters:
>> +              * register offset
>> +      required:
>> +        - amlogic,reg-layout
>> +        - clock-names
>> +
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: amlogic,a9-sysbus-ccu
>> +    then:
>> +      properties:
>> +        clocks:
>> +          maxItems: 1
>> +          description: input clock of sysbus-ccu
> 
> list the items with description instead.
> 
>> +        amlogic,reg-layout:
>> +          description: |
>> +            composite-ccu contains two register layout parameters:
>> +              * register offset
>> +              * bit offset
>> +      required:
>> +        - amlogic,reg-layout
> 
> This is huge and amount of ifs is clearly suggesting you combined way
> too much into one file.
> 

I'll try to split large blocks of if statements like this into separate 
.yaml files. Thanks for your suggestion.

> 
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - clocks
>> +  - clock-output-names
>> +  - "#clock-cells"
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    clk_dummy: clock-dummy {
>> +        compatible = "fixed-clock";
>> +        #clock-cells = <0>;
>> +        clock-frequency = <0>;
>> +        clock-output-names = "dummy";
>> +        status = "disabled";
>> +    };
> 
> Not relevant, drop entire node.
> 
>> +
>> +    apb {
>> +        #address-cells = <2>;
>> +        #size-cells = <2>;
>> +        clock-controller@350 {
>> +            compatible = "amlogic,a9-composite-ccu";
>> +            reg = <0x0 0x350 0x0 0x4>;
>> +            #clock-cells = <0>;
>> +            amlogic,clock-max-frequency = <50000000>;
>> +            amlogic,reg-layout = <0x0 0  7>;
>> +            clock-output-names = "sar_adc";
>> +            clocks = <&xtal_24m>,
>> +                     <&scmi_clk 17>;
>> +            clock-names = "clkin0", "clkin1";
>> +        };
>> +
>> +        clock-controller@290 {
>> +            compatible = "amlogic,a9-composite-ccu-mult";
>> +            reg = <0x0 0x290 0x0 0x8>;
>> +            #clock-cells = <1>;
>> +            amlogic,clock-max-frequency = <250000000>,
>> +                                          <250000000>,
>> +                                          <1200000000>;
>> +            amlogic,reg-layout = <0x0 0  7>,
>> +                                 <0x0 16 7>,
>> +                                 <0x4 0  7>;
>> +            clock-output-names = "sd_emmc_a",
>> +                                 "sd_emmc_b",
>> +                                 "sd_emmc_c";
>> +            clocks = <&xtal_24m>,
>> +                     <&scmi_clk 6>,
>> +                     <&scmi_clk 10>;
>> +            clock-names = "clkin0",
>> +                          "clkin1",
>> +                          "clkin2";
>> +        };
> 
> One or two are enough. Drop the rest.
> 

I have no objections to the comments here or the earlier ones I haven't 
replied to. To avoid taking up more of your time, I didn't reply one by 
one here. Thanks again.

>>
> 
> 
> Best regards,
> Krzysztof

-- 
Best regards,
Chuan


^ permalink raw reply

* Re: [PATCH v21 3/8] dt-bindings: display: bridge: Add Cadence MHDP8501
From: Laurentiu Palcu @ 2026-04-08 14:36 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: imx, Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, dri-devel, Alexander Stein,
	Dmitry Baryshkov, Ying Liu, devicetree, linux-kernel
In-Reply-To: <277cdf3b-7032-4847-9c22-bddae2a76b34@kernel.org>

On Wed, Apr 08, 2026 at 09:32:54AM +0200, Krzysztof Kozlowski wrote:
> On 08/04/2026 09:13, Laurentiu Palcu wrote:
> >>> +  phys:
> >>> +    maxItems: 1
> >>> +    description:
> >>> +      phandle to the DP/HDMI PHY
> >>> +
> >>> +  interrupts:
> >>> +    items:
> >>> +      - description: Hotplug cable plugin.
> >>> +      - description: Hotplug cable plugout.
> >>> +
> >>> +  interrupt-names:
> >>> +    items:
> >>> +      - const: plug_in
> >>> +      - const: plug_out
> >>> +
> >>> +  cdns,bridge-type:
> >>
> >> Drop property. Graph defines what is connected on the other side. And if
> >> this is for different devices then compatible tells what bridge is that.
> > 
> > Initially, Sandor did use the remote compatible to decide the bridge
> > type but he assumed the remote is always the connector. However, as
> > Dmitry pointed out [1], this is not reliable as we can have another bridge
> > in-between this one and the connector.
> > 
> > [1] https://lore.kernel.org/all/dpj333mzr5azqhrgw3cxd7x5kiwxms4iomwy74uqfhr2zu4ocr@36rkth27d2jc/
> 
> So you still know what is on the other side, e.g. second bridge for HDMI
> or DP, even if this is DP over USB-C.
> 
> I understand that Dmitry did not want to use that part of code in the
> drivers, but what is located at the end is not really a separate
> property of this bridge, because it already duplicates that information.
> The final endpoint defines the type.

Ok, I'll drop the property and add a routine to traverse the graph and
find the last endpoint.

-- 
Thanks,
Laurentiu

^ permalink raw reply

* Re: [PATCH 04/13] clk: amlogic: Add basic clock driver
From: Chuan Liu @ 2026-04-08 14:32 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Neil Armstrong, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
	Martin Blumenstingl
In-Reply-To: <89cc0724-32a8-4da5-8070-c128cafcfc82@kernel.org>

Hi Krzysztof (& ALL),
Thanks for review.

On 2/9/2026 9:17 PM, Krzysztof Kozlowski wrote:
> [ EXTERNAL EMAIL ]
> 
> On 09/02/2026 06:48, Chuan Liu via B4 Relay wrote:
>> From: Chuan Liu <chuan.liu@amlogic.com>
>>
>> Implement core clock driver for Amlogic SoC platforms, supporting
> 
> So how did all existing Amlogic SoC platforms work so far without basic
> clock driver? Really, how?
> 
> You are suppose to grow existing code, not add your completely new
> "basic" driver just because you have it that way in downstream.
> 

Firstly, apologies for the delayed response. I had intended to 
consolidate the V1 review feedback and come back with a clearer plan for 
V2 changes. In the meantime, Martin has provided many detailed and 
valuable suggestions - much appreciated.

The original goal of optimizing the HW based on A9 and introducing a new 
clock driver is to reduce unnecessary complexity in the driver. On A9, 
we optimized the Clock/PLL controller HW to simplify driver performance, 
complexity, memory footprint, and reusability. Improvements on the HW 
side can also help drive corresponding enhancements in the driver:
    - Performance: Encapsulates sub-clock functions, reducing call paths
    - Complexity: Standardized register bits eliminate a large number of
bit definitions (~1/3 of original code is defined register bit [1])
    - Memory: Object-oriented design avoids copy/paste for repeated clocks
    - Reusability: Same controller works across SoCs without driver
changes (or with minimal changes)

The old meson driver required compromises to unify legacy controller
characteristics and driver styles. On A9, we want a fresh start.

> Best regards,
> Krzysztof

-- 
Best regards,
Chuan


^ permalink raw reply

* Re: [PATCH V3 1/9] dt-bindings: iio: imu: icm42607: Add devicetree binding
From: Chris Morgan @ 2026-04-08 14:31 UTC (permalink / raw)
  To: Rob Herring
  Cc: Chris Morgan, linux-iio, andy, nuno.sa, dlechner, jic23,
	jean-baptiste.maneyrol, linux-rockchip, devicetree, heiko,
	conor+dt, krzk+dt, andriy.shevchenko
In-Reply-To: <20260408131944.GA1901621-robh@kernel.org>

On Wed, Apr 08, 2026 at 08:19:44AM -0500, Rob Herring wrote:
> On Mon, Mar 30, 2026 at 02:58:45PM -0500, Chris Morgan wrote:
> > From: Chris Morgan <macromorgan@hotmail.com>
> > 
> Subject space is limited, so don't say devicetree binding twice:
> 
> dt-bindings: iio: imu: Add Invensense ICM42607
> 
> > Add devicetree binding for the Invensense ICM42607 and Invensense
> > ICM42607P inertial measurement unit. This unit is a combined
> > accelerometer, gyroscope, and thermometer available via I2C or SPI.
> > 
> > This device is functionally very similar to the icm42600 series with a
> > very different register layout.
> 
> Similar enough to use the same binding schema?

Yes. I was under the (possibly mistaken) impression that different drivers
required different binding schemas, but these should be similar enough to
use the same schema if it's allowed.

Thank you,
Chris

> 
> > Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
> > ---
> >  .../bindings/iio/imu/invensense,icm42607.yaml | 95 +++++++++++++++++++
> >  1 file changed, 95 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/iio/imu/invensense,icm42607.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,icm42607.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,icm42607.yaml
> > new file mode 100644
> > index 000000000000..bbacdee5b906
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/iio/imu/invensense,icm42607.yaml
> > @@ -0,0 +1,95 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/iio/imu/invensense,icm42607.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: InvenSense ICM-42607 Inertial Measurement Unit
> > +
> > +maintainers:
> > +  - Chris Morgan <macromorgan@hotmail.com>
> > +
> > +description: |
> 
> Don't need '|'.
> 
> > +  6-axis MotionTracking device that combines a 3-axis gyroscope and a 3-axis
> > +  accelerometer.
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - invensense,icm42607
> > +      - invensense,icm42607p
> 
> blank line
> 
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    minItems: 1
> > +    maxItems: 2
> > +
> > +  interrupt-names:
> > +    minItems: 1
> > +    maxItems: 2
> > +    items:
> > +      enum:
> > +        - INT1
> > +        - INT2
> > +
> > +  drive-open-drain:
> > +    type: boolean
> > +
> > +  mount-matrix: true
> > +
> > +  spi-cpha: true
> > +  spi-cpol: true
> > +
> > +  vdd-supply:
> > +    description: Regulator that provides power to the sensor
> > +
> > +  vddio-supply:
> > +    description: Regulator that provides power to the bus
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +
> > +allOf:
> > +  - $ref: /schemas/spi/spi-peripheral-props.yaml#
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    i2c {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        icm42607p@68 {
> > +            compatible = "invensense,icm42607p";
> > +            reg = <0x68>;
> > +            interrupt-parent = <&gpio2>;
> > +            interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
> > +            interrupt-names = "INT1";
> > +            vdd-supply = <&vdd>;
> > +            vddio-supply = <&vddio>;
> > +        };
> > +    };
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    spi {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        icm42607p@0 {
> > +            compatible = "invensense,icm42607p";
> > +            reg = <0>;
> > +            spi-max-frequency = <24000000>;
> > +            spi-cpha;
> > +            spi-cpol;
> > +            interrupt-parent = <&gpio1>;
> > +            interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
> > +            interrupt-names = "INT1";
> > +            vdd-supply = <&vdd>;
> > +            vddio-supply = <&vddio>;
> > +        };
> > +    };
> > -- 
> > 2.43.0
> > 

^ permalink raw reply

* Re: [PATCH v2 2/7] dt-bindings: soc: samsung: exynos-pmu: add samsung,pmu-intr-gen phandle
From: Alexey Klimov @ 2026-04-08 14:30 UTC (permalink / raw)
  To: André Draszik, Sam Protsenko, linux-samsung-soc,
	Krzysztof Kozlowski, Peter Griffin, Conor Dooley, Alim Akhtar
  Cc: Tudor Ambarus, Rob Herring, Krzysztof Kozlowski, linux-arm-kernel,
	devicetree, linux-kernel
In-Reply-To: <01ffe5d3aca040edcedb084386ab6e195cb93013.camel@linaro.org>

Hi André,

On Fri Apr 3, 2026 at 11:17 AM BST, André Draszik wrote:
> Hi Alexey,
>
> On Wed, 2026-04-01 at 05:51 +0100, Alexey Klimov wrote:
>> Some Exynos-based SoCs, for instance Exynos850, require access
>> to the pmu interrupt generation register region which is exposed
>> as a syscon. Update the exynos-pmu bindings documentation to
>> reflect this.
>
> You could mention that this is similar to the existing google,...
> one due to same requirement, hence a new and more general property.

Ok. Thanks.

>> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
>> ---
>>  .../devicetree/bindings/soc/samsung/exynos-pmu.yaml    | 18 ++++++++++++++++++
>>  1 file changed, 18 insertions(+)
>> 
>> diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-
>> pmu.yaml
>> index 76ce7e98c10f..92acdfd5d44e 100644
>> --- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
>> +++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
>> @@ -110,6 +110,11 @@ properties:
>>      description:
>>        Node for reboot method
>>  
>> +  samsung,pmu-intr-gen-syscon:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description:
>> +      Phandle to PMU interrupt generation interface.
>> +
>>    google,pmu-intr-gen-syscon:
>
> Please keep alphabetical order of vendors.

Sure. Thanks for noticing this.

Best regards,
Alexey

^ permalink raw reply

* Re: [PATCH v6 13/21] drm: renesas: rz-du: mipi_dsi: Add RZ_MIPI_DSI_FEATURE_GPO0R feature
From: Laurent Pinchart @ 2026-04-08 14:17 UTC (permalink / raw)
  To: Tommaso Merciai
  Cc: tomm.merciai, geert, linux-renesas-soc, biju.das.jz,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Magnus Damm,
	Tomi Valkeinen, dri-devel, devicetree, linux-kernel, linux-clk
In-Reply-To: <b8ded729-5c22-4a47-bfb7-8bffeed76e98@bp.renesas.com>

On Wed, Apr 08, 2026 at 04:12:22PM +0200, Tommaso Merciai wrote:
> Hi Laurent,
> Thanks for your review.
> 
> On 4/8/26 14:31, Laurent Pinchart wrote:
> > On Wed, Apr 08, 2026 at 12:36:58PM +0200, Tommaso Merciai wrote:
> >> The MIPI DSI ip found in the RZ/G3E SoC select the video input clock
> >> based on the DU instance actually connected using the GPO0R register.
> >>
> >> Add this feature to the driver using `RZ_MIPI_DSI_FEATURE_GPO0R`, update
> >> the code accordingly to manage the vclk selection with the introduction
> >> of `rzg2l_mipi_dsi_get_input_port()`.
> >>
> >> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
> >> ---
> >> v5->v6:
> >>   - Moved rzg2l_mipi_dsi_link_write() into rzv2h_mipi_dsi_dphy_init()
> >>     + comments from HW Manual.
> >>
> >> v4->v5:
> >>   - No changes.
> >>
> >> v3->v4:
> >>   - No changes.
> >>
> >> v2->v3:
> >>   - No changes.
> >>
> >> v1->v2:
> >>   - No changes.
> >>
> >>   .../gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c    | 71 +++++++++++++++++--
> >>   .../drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h   |  3 +
> >>   2 files changed, 68 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
> >> index be6dbf19a24e..947c8e15fc4b 100644
> >> --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
> >> +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
> >> @@ -37,7 +37,9 @@ MODULE_IMPORT_NS("RZV2H_CPG");
> >>   
> >>   #define RZG2L_DCS_BUF_SIZE	128 /* Maximum DCS buffer size in external memory. */
> >>   
> >> +#define RZ_MIPI_DSI_MAX_INPUT	2
> >>   #define RZ_MIPI_DSI_FEATURE_16BPP	BIT(0)
> >> +#define RZ_MIPI_DSI_FEATURE_GPO0R	BIT(1)
> >>   
> >>   struct rzg2l_mipi_dsi;
> >>   
> >> @@ -81,13 +83,14 @@ struct rzg2l_mipi_dsi {
> >>   	struct drm_bridge bridge;
> >>   	struct drm_bridge *next_bridge;
> >>   
> >> -	struct clk *vclk;
> >> +	struct clk *vclk[RZ_MIPI_DSI_MAX_INPUT];
> >>   	struct clk *lpclk;
> >>   
> >>   	enum mipi_dsi_pixel_format format;
> >>   	unsigned int num_data_lanes;
> >>   	unsigned int lanes;
> >>   	unsigned long mode_flags;
> >> +	u8 vclk_idx;
> >>   
> >>   	struct rzv2h_dsi_mode_calc mode_calc;
> >>   
> >> @@ -543,8 +546,8 @@ static int rzg2l_dphy_conf_clks(struct rzg2l_mipi_dsi *dsi, unsigned long mode_f
> >>   	unsigned long vclk_rate;
> >>   	unsigned int bpp;
> >>   
> >> -	clk_set_rate(dsi->vclk, mode_freq * KILO);
> >> -	vclk_rate = clk_get_rate(dsi->vclk);
> >> +	clk_set_rate(dsi->vclk[dsi->vclk_idx], mode_freq * KILO);
> >> +	vclk_rate = clk_get_rate(dsi->vclk[dsi->vclk_idx]);
> >>   	if (vclk_rate != mode_freq * KILO)
> >>   		dev_dbg(dsi->dev, "Requested vclk rate %lu, actual %lu mismatch\n",
> >>   			mode_freq * KILO, vclk_rate);
> >> @@ -687,6 +690,19 @@ static int rzv2h_mipi_dsi_dphy_init(struct rzg2l_mipi_dsi *dsi,
> >>   	rzg2l_mipi_dsi_phy_write(dsi, PLLCLKSET1R,
> >>   				 FIELD_PREP(PLLCLKSET1R_PLL_K, dsi_parameters->k));
> >>   
> >> +	/*
> >> +	 * From RZ/G3E HW manual (Rev.1.15) section 9.5.3 Operation,
> >> +	 * 9.5.3.1 Power on Reset and Initial Settings for All Operations.
> >> +	 * Figure 9.5-4 Power On/Off Sequence show that after writing to
> >> +	 * GPO0R.VICH register we need to wait for more than 1 x tp before
> >> +	 * writing to PLLENR.PLLEN.
> >> +	 *
> >> +	 * Note: GPO0R is a link register, not a PHY register. This setting
> >> +	 * is specific to RZ/G3E.
> >> +	 */
> >> +	if (dsi->info->features & RZ_MIPI_DSI_FEATURE_GPO0R)
> >> +		rzg2l_mipi_dsi_link_write(dsi, GPO0R, dsi->vclk_idx);
> >> +
> >>   	/*
> >>   	 * From RZ/V2H HW manual (Rev.1.20) section 9.5.3 Operation,
> >>   	 * (C) After write to D-PHY registers we need to wait for more than 1 x tp
> >> @@ -1005,6 +1021,37 @@ static int rzg2l_mipi_dsi_stop_video(struct rzg2l_mipi_dsi *dsi)
> >>   	return ret;
> >>   }
> >>   
> >> +static int rzg2l_mipi_dsi_get_input_port(struct rzg2l_mipi_dsi *dsi)
> >> +{
> >> +	struct device_node *np = dsi->dev->of_node;
> >> +	struct device_node *remote_ep, *ep_node;
> >> +	struct of_endpoint ep;
> >> +	bool ep_enabled;
> >> +	int in_port;
> >> +
> >> +	/* DSI can have only one port enabled */
> > 
> > Why is that ? The hardware supports dynamic input selection, why can't
> > it be supported at runtime ?
> 
> For runtime/dynamic you mean using DT overlay??
> like, remove:
> 
> Removing - DU0 --> DSI (input 0 | port@0 ) overlay and
> install  - DU1 --> DSI (input 1 | port@1 ) overlay and
> viceversa?

No, I mean configurable by userspace, with two CRTCs sharing one DSI
encoder.

> >> +	for_each_endpoint_of_node(np, ep_node) {
> >> +		of_graph_parse_endpoint(ep_node, &ep);
> >> +		if (ep.port >= RZ_MIPI_DSI_MAX_INPUT)
> >> +			break;
> >> +
> >> +		remote_ep = of_graph_get_remote_endpoint(ep_node);
> >> +		ep_enabled = of_device_is_available(remote_ep);
> >> +		of_node_put(remote_ep);
> >> +
> >> +		if (ep_enabled) {
> >> +			in_port = ep.port;
> >> +			break;
> >> +		}
> >> +	}
> >> +
> >> +	if (!ep_enabled)
> >> +		return -EINVAL;
> >> +
> >> +	dev_dbg(dsi->dev, "input port@%d\n", in_port);
> >> +	return in_port;
> >> +}
> >> +
> >>   /* -----------------------------------------------------------------------------
> >>    * Bridge
> >>    */
> >> @@ -1425,9 +1472,21 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev)
> >>   	if (IS_ERR(dsi->mmio))
> >>   		return PTR_ERR(dsi->mmio);
> >>   
> >> -	dsi->vclk = devm_clk_get(dsi->dev, "vclk");
> >> -	if (IS_ERR(dsi->vclk))
> >> -		return PTR_ERR(dsi->vclk);
> >> +	dsi->vclk[0] = devm_clk_get(dsi->dev, "vclk");
> >> +		if (IS_ERR(dsi->vclk[0]))
> >> +			return PTR_ERR(dsi->vclk[0]);
> >> +
> >> +	if (dsi->info->features & RZ_MIPI_DSI_FEATURE_GPO0R) {
> >> +		dsi->vclk[1] = devm_clk_get(dsi->dev, "vclk2");
> >> +		if (IS_ERR(dsi->vclk[1]))
> >> +			return PTR_ERR(dsi->vclk[1]);
> >> +
> >> +		ret = rzg2l_mipi_dsi_get_input_port(dsi);
> >> +		if (ret < 0)
> >> +			return dev_err_probe(dsi->dev, -EINVAL,
> >> +					     "No available input port\n");
> >> +		dsi->vclk_idx = ret;
> >> +	}
> >>   
> >>   	dsi->lpclk = devm_clk_get(dsi->dev, "lpclk");
> >>   	if (IS_ERR(dsi->lpclk))
> >> diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
> >> index 2bef20566648..cee2e0bc5dc5 100644
> >> --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
> >> +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
> >> @@ -83,6 +83,9 @@
> >>   #define LINKSR_SQCHRUN1			BIT(4)
> >>   #define LINKSR_SQCHRUN0			BIT(0)
> >>   
> >> +/* RZ/G3E General Purpose Output 0 Register */
> >> +#define GPO0R				0xc0
> >> +
> >>   /* Tx Set Register */
> >>   #define TXSETR				0x100
> >>   #define TXSETR_NUMLANECAP		(0x3 << 16)

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH v6 10/21] dt-bindings: display: renesas,rzg2l-du: Add support for RZ/G3E SoC
From: Laurent Pinchart @ 2026-04-08 14:16 UTC (permalink / raw)
  To: Tommaso Merciai
  Cc: tomm.merciai, geert, linux-renesas-soc, biju.das.jz,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Magnus Damm,
	Tomi Valkeinen, dri-devel, devicetree, linux-kernel, linux-clk
In-Reply-To: <dafdbdcf-98db-473c-8122-296af1922e6c@bp.renesas.com>

On Wed, Apr 08, 2026 at 04:02:14PM +0200, Tommaso Merciai wrote:
> Hi Laurent,
> Thanks for your review.
> 
> On 4/8/26 14:24, Laurent Pinchart wrote:
> > On Wed, Apr 08, 2026 at 12:36:55PM +0200, Tommaso Merciai wrote:
> >> The RZ/G3E SoC has 2 LCD controllers (LCDC), each containing a Frame
> >> Compression Processor (FCPVD), a Video Signal Processor (VSPD), and a
> >> Display Unit (DU).
> >>
> >>   - LCDC0 supports DSI and LVDS (single or dual-channel) outputs.
> >>   - LCDC1 supports DSI, LVDS (single-channel), and RGB outputs.
> >>
> >> Add a new SoC-specific compatible string 'renesas,r9a09g047-du'.
> >>
> >> Extend patternProperties from "^port@[0-1]$" to "^port@[0-3]$" to
> >> allow up to four output ports, and explicitly disable port@2 and port@3
> >> for existing SoCs that do not expose them.
> >>
> >> Describe the four output ports of the RZ/G3E DU:
> >>
> >>   - port@0: DSI (available on both LCDC instances)
> >>   - port@1: DPAD / parallel RGB (LCDC1 only)
> >>   - port@2: LVDS channel 0 (LCDC0 only)
> >>   - port@3: LVDS channel 1 (available on both LCDC instances)
> >>
> >> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
> >> ---
> >> v5->v6:
> >>   - Extend patternProperties from "^port@[0-1]$" to "^port@[0-3]$" and
> >>     explicitly disable port@2 and port@3 for existing SoCs that do not expose
> >>     them.
> >>   - Reworked ports numbering + improved/fixed ports descriptions in the
> >>     bindings documentation.
> >>   - Improved commit body.
> >>
> >> v4->v5:
> >>   - Dropped renesas,id property and updated bindings
> >>     accordingly.
> >>
> >> v2->v3:
> >>   - No changes.
> >>
> >> v2->v3:
> >>   - No changes.
> >>
> >> v1->v2:
> >>   - Use single compatible string instead of multiple compatible strings
> >>     for the two DU instances, leveraging a 'renesas,id' property to
> >>     differentiate between DU0 and DU1.
> >>   - Updated commit message accordingly.
> >>
> >>   .../bindings/display/renesas,rzg2l-du.yaml    | 30 ++++++++++++++++++-
> >>   1 file changed, 29 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
> >> index 5add3b832eab..32da0b5ec88c 100644
> >> --- a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
> >> +++ b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
> >> @@ -20,6 +20,7 @@ properties:
> >>         - enum:
> >>             - renesas,r9a07g043u-du # RZ/G2UL
> >>             - renesas,r9a07g044-du # RZ/G2{L,LC}
> >> +          - renesas,r9a09g047-du # RZ/G3E
> >>             - renesas,r9a09g057-du # RZ/V2H(P)
> >>         - items:
> >>             - enum:
> >> @@ -61,7 +62,7 @@ properties:
> >>         model-dependent. Each port shall have a single endpoint.
> >>   
> >>       patternProperties:
> >> -      "^port@[0-1]$":
> >> +      "^port@[0-3]$":
> >>           $ref: /schemas/graph.yaml#/properties/port
> >>           unevaluatedProperties: false
> >>   
> >> @@ -103,6 +104,8 @@ allOf:
> >>               port@0:
> >>                 description: DPI
> >>               port@1: false
> >> +            port@2: false
> >> +            port@3: false
> >>   
> >>             required:
> >>               - port@0
> >> @@ -119,6 +122,8 @@ allOf:
> >>                 description: DSI
> >>               port@1:
> >>                 description: DPI
> >> +            port@2: false
> >> +            port@3: false
> >>   
> >>             required:
> >>               - port@0
> >> @@ -135,9 +140,32 @@ allOf:
> >>               port@0:
> >>                 description: DSI
> >>               port@1: false
> >> +            port@2: false
> >> +            port@3: false
> >>   
> >>             required:
> >>               - port@0
> >> +  - if:
> >> +      properties:
> >> +        compatible:
> >> +          contains:
> >> +            const: renesas,r9a09g047-du
> >> +    then:
> >> +      properties:
> >> +        ports:
> >> +          properties:
> >> +            port@0:
> >> +              description: DSI
> >> +            port@1:
> >> +              description: DPAD
> >> +            port@2:
> >> +              description: LVDS, Channel 0
> >> +            port@3:
> >> +              description: LVDS, Channel 1
> >> +
> >> +          required:
> >> +            - port@0
> >> +            - port@3
> > 
> > Why are ports 1 and 2 not required ?
> 
> About this we had a similar discussion on v5[0]
> We are using the same compatible and:
> 
> - LCDC0 supports DSI and LVDS (single or dual-channel) outputs.
> |
> --> then has:
> 	port@0
> 	port@2
> 	port@3
> 	
> 
>   - LCDC1 supports DSI, LVDS (single-channel), and RGB outputs.
> |
> --> then has:
> 	port@0
> 	port@1
> 	port@3

Ah yes, I forget there are two LCDC instances with different output
configurations.

Something still looks a bit weird to me though. For LCDC1, which
supports a single LVDS channel, you use the port described as the second
LVDS channel. Is there a reason not to use port@2 ?

> Then port@1 is required for DU1 but not for DU0.
> Same port@2 is required for DU0 but not for DU1.
> 
> [0] https://patchwork.kernel.org/project/linux-renesas-soc/patch/ca022fdbba5236c36e0cb3095db4c31e8e0cb1b8.1770996493.git.tommaso.merciai.xr@bp.renesas.com/ 
>
> >>
> >>   examples:
> >>     # RZ/G2L DU

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* [PATCH v2 2/2] pinctrl: qcom: Add Hawi pinctrl driver
From: Mukesh Ojha @ 2026-04-08 14:15 UTC (permalink / raw)
  To: Bjorn Andersson, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Mukesh Ojha
  Cc: linux-arm-msm, linux-gpio, devicetree, linux-kernel,
	Konrad Dybcio
In-Reply-To: <20260408-hawi-pinctrl-v2-0-fd7f681f5e05@oss.qualcomm.com>

Add pinctrl driver for TLMM block found in the Hawi SoC.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/pinctrl/qcom/Kconfig.msm    |   10 +
 drivers/pinctrl/qcom/Makefile       |    1 +
 drivers/pinctrl/qcom/pinctrl-hawi.c | 1610 +++++++++++++++++++++++++++++++++++
 3 files changed, 1621 insertions(+)

diff --git a/drivers/pinctrl/qcom/Kconfig.msm b/drivers/pinctrl/qcom/Kconfig.msm
index 17416dce8e70..836cdeca1006 100644
--- a/drivers/pinctrl/qcom/Kconfig.msm
+++ b/drivers/pinctrl/qcom/Kconfig.msm
@@ -35,6 +35,16 @@ config PINCTRL_GLYMUR
 	  Say Y here to compile statically, or M here to compile it as a module.
 	  If unsure, say N.
 
+config PINCTRL_HAWI
+	tristate "Qualcomm Technologies Inc Hawi pin controller driver"
+	depends on ARM64 || COMPILE_TEST
+	help
+	  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+	  Qualcomm Technologies Inc Top Level Mode Multiplexer block (TLMM)
+	  block found on the Qualcomm Technologies Inc Hawi platform.
+	  Say Y here to compile statically, or M here to compile it as a module.
+	  If unsure, say N.
+
 config PINCTRL_IPQ4019
 	tristate "Qualcomm IPQ4019 pin controller driver"
 	depends on ARM || COMPILE_TEST
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 4c585bad813c..84bda3ada874 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PINCTRL_APQ8064)	+= pinctrl-apq8064.o
 obj-$(CONFIG_PINCTRL_APQ8084)	+= pinctrl-apq8084.o
 obj-$(CONFIG_PINCTRL_ELIZA)	+= pinctrl-eliza.o
 obj-$(CONFIG_PINCTRL_GLYMUR)	+= pinctrl-glymur.o
+obj-$(CONFIG_PINCTRL_HAWI)	+= pinctrl-hawi.o
 obj-$(CONFIG_PINCTRL_IPQ4019)	+= pinctrl-ipq4019.o
 obj-$(CONFIG_PINCTRL_IPQ5018)	+= pinctrl-ipq5018.o
 obj-$(CONFIG_PINCTRL_IPQ8064)	+= pinctrl-ipq8064.o
diff --git a/drivers/pinctrl/qcom/pinctrl-hawi.c b/drivers/pinctrl/qcom/pinctrl-hawi.c
new file mode 100644
index 000000000000..5c7894f3b9cb
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-hawi.c
@@ -0,0 +1,1610 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-msm.h"
+
+#define REG_SIZE 0x1000
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \
+	{						\
+		.grp = PINCTRL_PINGROUP("gpio" #id,	\
+			gpio##id##_pins,		\
+			ARRAY_SIZE(gpio##id##_pins)),	\
+		.funcs = (int[]){			\
+			msm_mux_gpio, /* gpio mode */	\
+			msm_mux_##f1,			\
+			msm_mux_##f2,			\
+			msm_mux_##f3,			\
+			msm_mux_##f4,			\
+			msm_mux_##f5,			\
+			msm_mux_##f6,			\
+			msm_mux_##f7,			\
+			msm_mux_##f8,			\
+			msm_mux_##f9,			\
+			msm_mux_##f10,			\
+			msm_mux_##f11 /* egpio mode */	\
+		},					\
+		.nfuncs = 12,				\
+		.ctl_reg = REG_SIZE * id,		\
+		.io_reg = 0x4 + REG_SIZE * id,		\
+		.intr_cfg_reg = 0x8 + REG_SIZE * id,	\
+		.intr_status_reg = 0xc + REG_SIZE * id,	\
+		.mux_bit = 2,				\
+		.pull_bit = 0,				\
+		.drv_bit = 6,				\
+		.egpio_enable = 12,			\
+		.egpio_present = 11,			\
+		.oe_bit = 9,				\
+		.in_bit = 0,				\
+		.out_bit = 1,				\
+		.intr_enable_bit = 0,			\
+		.intr_status_bit = 0,			\
+		.intr_wakeup_present_bit = 6,	\
+		.intr_wakeup_enable_bit = 7,	\
+		.intr_target_bit = 8,			\
+		.intr_target_kpss_val = 3,		\
+		.intr_raw_status_bit = 4,		\
+		.intr_polarity_bit = 1,			\
+		.intr_detection_bit = 2,		\
+		.intr_detection_width = 2,		\
+	}
+
+#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv)	\
+	{					        \
+		.grp = PINCTRL_PINGROUP(#pg_name,	\
+			pg_name##_pins,			\
+			ARRAY_SIZE(pg_name##_pins)),	\
+		.ctl_reg = ctl,				\
+		.io_reg = 0,				\
+		.intr_cfg_reg = 0,			\
+		.intr_status_reg = 0,			\
+		.intr_target_reg = 0,			\
+		.mux_bit = -1,				\
+		.pull_bit = pull,			\
+		.drv_bit = drv,				\
+		.oe_bit = -1,				\
+		.in_bit = -1,				\
+		.out_bit = -1,				\
+		.intr_enable_bit = -1,			\
+		.intr_status_bit = -1,			\
+		.intr_target_bit = -1,			\
+		.intr_raw_status_bit = -1,		\
+		.intr_polarity_bit = -1,		\
+		.intr_detection_bit = -1,		\
+		.intr_detection_width = -1,		\
+	}
+
+#define UFS_RESET(pg_name, ctl, io)			\
+	{						\
+		.grp = PINCTRL_PINGROUP(#pg_name,	\
+			pg_name##_pins,			\
+			ARRAY_SIZE(pg_name##_pins)),	\
+		.ctl_reg = ctl,				\
+		.io_reg = io,				\
+		.intr_cfg_reg = 0,			\
+		.intr_status_reg = 0,			\
+		.intr_target_reg = 0,			\
+		.mux_bit = -1,				\
+		.pull_bit = 3,				\
+		.drv_bit = 0,				\
+		.oe_bit = -1,				\
+		.in_bit = -1,				\
+		.out_bit = 0,				\
+		.intr_enable_bit = -1,			\
+		.intr_status_bit = -1,			\
+		.intr_target_bit = -1,			\
+		.intr_raw_status_bit = -1,		\
+		.intr_polarity_bit = -1,		\
+		.intr_detection_bit = -1,		\
+		.intr_detection_width = -1,		\
+	}
+
+static const struct pinctrl_pin_desc hawi_pins[] = {
+	PINCTRL_PIN(0, "GPIO_0"),
+	PINCTRL_PIN(1, "GPIO_1"),
+	PINCTRL_PIN(2, "GPIO_2"),
+	PINCTRL_PIN(3, "GPIO_3"),
+	PINCTRL_PIN(4, "GPIO_4"),
+	PINCTRL_PIN(5, "GPIO_5"),
+	PINCTRL_PIN(6, "GPIO_6"),
+	PINCTRL_PIN(7, "GPIO_7"),
+	PINCTRL_PIN(8, "GPIO_8"),
+	PINCTRL_PIN(9, "GPIO_9"),
+	PINCTRL_PIN(10, "GPIO_10"),
+	PINCTRL_PIN(11, "GPIO_11"),
+	PINCTRL_PIN(12, "GPIO_12"),
+	PINCTRL_PIN(13, "GPIO_13"),
+	PINCTRL_PIN(14, "GPIO_14"),
+	PINCTRL_PIN(15, "GPIO_15"),
+	PINCTRL_PIN(16, "GPIO_16"),
+	PINCTRL_PIN(17, "GPIO_17"),
+	PINCTRL_PIN(18, "GPIO_18"),
+	PINCTRL_PIN(19, "GPIO_19"),
+	PINCTRL_PIN(20, "GPIO_20"),
+	PINCTRL_PIN(21, "GPIO_21"),
+	PINCTRL_PIN(22, "GPIO_22"),
+	PINCTRL_PIN(23, "GPIO_23"),
+	PINCTRL_PIN(24, "GPIO_24"),
+	PINCTRL_PIN(25, "GPIO_25"),
+	PINCTRL_PIN(26, "GPIO_26"),
+	PINCTRL_PIN(27, "GPIO_27"),
+	PINCTRL_PIN(28, "GPIO_28"),
+	PINCTRL_PIN(29, "GPIO_29"),
+	PINCTRL_PIN(30, "GPIO_30"),
+	PINCTRL_PIN(31, "GPIO_31"),
+	PINCTRL_PIN(32, "GPIO_32"),
+	PINCTRL_PIN(33, "GPIO_33"),
+	PINCTRL_PIN(34, "GPIO_34"),
+	PINCTRL_PIN(35, "GPIO_35"),
+	PINCTRL_PIN(36, "GPIO_36"),
+	PINCTRL_PIN(37, "GPIO_37"),
+	PINCTRL_PIN(38, "GPIO_38"),
+	PINCTRL_PIN(39, "GPIO_39"),
+	PINCTRL_PIN(40, "GPIO_40"),
+	PINCTRL_PIN(41, "GPIO_41"),
+	PINCTRL_PIN(42, "GPIO_42"),
+	PINCTRL_PIN(43, "GPIO_43"),
+	PINCTRL_PIN(44, "GPIO_44"),
+	PINCTRL_PIN(45, "GPIO_45"),
+	PINCTRL_PIN(46, "GPIO_46"),
+	PINCTRL_PIN(47, "GPIO_47"),
+	PINCTRL_PIN(48, "GPIO_48"),
+	PINCTRL_PIN(49, "GPIO_49"),
+	PINCTRL_PIN(50, "GPIO_50"),
+	PINCTRL_PIN(51, "GPIO_51"),
+	PINCTRL_PIN(52, "GPIO_52"),
+	PINCTRL_PIN(53, "GPIO_53"),
+	PINCTRL_PIN(54, "GPIO_54"),
+	PINCTRL_PIN(55, "GPIO_55"),
+	PINCTRL_PIN(56, "GPIO_56"),
+	PINCTRL_PIN(57, "GPIO_57"),
+	PINCTRL_PIN(58, "GPIO_58"),
+	PINCTRL_PIN(59, "GPIO_59"),
+	PINCTRL_PIN(60, "GPIO_60"),
+	PINCTRL_PIN(61, "GPIO_61"),
+	PINCTRL_PIN(62, "GPIO_62"),
+	PINCTRL_PIN(63, "GPIO_63"),
+	PINCTRL_PIN(64, "GPIO_64"),
+	PINCTRL_PIN(65, "GPIO_65"),
+	PINCTRL_PIN(66, "GPIO_66"),
+	PINCTRL_PIN(67, "GPIO_67"),
+	PINCTRL_PIN(68, "GPIO_68"),
+	PINCTRL_PIN(69, "GPIO_69"),
+	PINCTRL_PIN(70, "GPIO_70"),
+	PINCTRL_PIN(71, "GPIO_71"),
+	PINCTRL_PIN(72, "GPIO_72"),
+	PINCTRL_PIN(73, "GPIO_73"),
+	PINCTRL_PIN(74, "GPIO_74"),
+	PINCTRL_PIN(75, "GPIO_75"),
+	PINCTRL_PIN(76, "GPIO_76"),
+	PINCTRL_PIN(77, "GPIO_77"),
+	PINCTRL_PIN(78, "GPIO_78"),
+	PINCTRL_PIN(79, "GPIO_79"),
+	PINCTRL_PIN(80, "GPIO_80"),
+	PINCTRL_PIN(81, "GPIO_81"),
+	PINCTRL_PIN(82, "GPIO_82"),
+	PINCTRL_PIN(83, "GPIO_83"),
+	PINCTRL_PIN(84, "GPIO_84"),
+	PINCTRL_PIN(85, "GPIO_85"),
+	PINCTRL_PIN(86, "GPIO_86"),
+	PINCTRL_PIN(87, "GPIO_87"),
+	PINCTRL_PIN(88, "GPIO_88"),
+	PINCTRL_PIN(89, "GPIO_89"),
+	PINCTRL_PIN(90, "GPIO_90"),
+	PINCTRL_PIN(91, "GPIO_91"),
+	PINCTRL_PIN(92, "GPIO_92"),
+	PINCTRL_PIN(93, "GPIO_93"),
+	PINCTRL_PIN(94, "GPIO_94"),
+	PINCTRL_PIN(95, "GPIO_95"),
+	PINCTRL_PIN(96, "GPIO_96"),
+	PINCTRL_PIN(97, "GPIO_97"),
+	PINCTRL_PIN(98, "GPIO_98"),
+	PINCTRL_PIN(99, "GPIO_99"),
+	PINCTRL_PIN(100, "GPIO_100"),
+	PINCTRL_PIN(101, "GPIO_101"),
+	PINCTRL_PIN(102, "GPIO_102"),
+	PINCTRL_PIN(103, "GPIO_103"),
+	PINCTRL_PIN(104, "GPIO_104"),
+	PINCTRL_PIN(105, "GPIO_105"),
+	PINCTRL_PIN(106, "GPIO_106"),
+	PINCTRL_PIN(107, "GPIO_107"),
+	PINCTRL_PIN(108, "GPIO_108"),
+	PINCTRL_PIN(109, "GPIO_109"),
+	PINCTRL_PIN(110, "GPIO_110"),
+	PINCTRL_PIN(111, "GPIO_111"),
+	PINCTRL_PIN(112, "GPIO_112"),
+	PINCTRL_PIN(113, "GPIO_113"),
+	PINCTRL_PIN(114, "GPIO_114"),
+	PINCTRL_PIN(115, "GPIO_115"),
+	PINCTRL_PIN(116, "GPIO_116"),
+	PINCTRL_PIN(117, "GPIO_117"),
+	PINCTRL_PIN(118, "GPIO_118"),
+	PINCTRL_PIN(119, "GPIO_119"),
+	PINCTRL_PIN(120, "GPIO_120"),
+	PINCTRL_PIN(121, "GPIO_121"),
+	PINCTRL_PIN(122, "GPIO_122"),
+	PINCTRL_PIN(123, "GPIO_123"),
+	PINCTRL_PIN(124, "GPIO_124"),
+	PINCTRL_PIN(125, "GPIO_125"),
+	PINCTRL_PIN(126, "GPIO_126"),
+	PINCTRL_PIN(127, "GPIO_127"),
+	PINCTRL_PIN(128, "GPIO_128"),
+	PINCTRL_PIN(129, "GPIO_129"),
+	PINCTRL_PIN(130, "GPIO_130"),
+	PINCTRL_PIN(131, "GPIO_131"),
+	PINCTRL_PIN(132, "GPIO_132"),
+	PINCTRL_PIN(133, "GPIO_133"),
+	PINCTRL_PIN(134, "GPIO_134"),
+	PINCTRL_PIN(135, "GPIO_135"),
+	PINCTRL_PIN(136, "GPIO_136"),
+	PINCTRL_PIN(137, "GPIO_137"),
+	PINCTRL_PIN(138, "GPIO_138"),
+	PINCTRL_PIN(139, "GPIO_139"),
+	PINCTRL_PIN(140, "GPIO_140"),
+	PINCTRL_PIN(141, "GPIO_141"),
+	PINCTRL_PIN(142, "GPIO_142"),
+	PINCTRL_PIN(143, "GPIO_143"),
+	PINCTRL_PIN(144, "GPIO_144"),
+	PINCTRL_PIN(145, "GPIO_145"),
+	PINCTRL_PIN(146, "GPIO_146"),
+	PINCTRL_PIN(147, "GPIO_147"),
+	PINCTRL_PIN(148, "GPIO_148"),
+	PINCTRL_PIN(149, "GPIO_149"),
+	PINCTRL_PIN(150, "GPIO_150"),
+	PINCTRL_PIN(151, "GPIO_151"),
+	PINCTRL_PIN(152, "GPIO_152"),
+	PINCTRL_PIN(153, "GPIO_153"),
+	PINCTRL_PIN(154, "GPIO_154"),
+	PINCTRL_PIN(155, "GPIO_155"),
+	PINCTRL_PIN(156, "GPIO_156"),
+	PINCTRL_PIN(157, "GPIO_157"),
+	PINCTRL_PIN(158, "GPIO_158"),
+	PINCTRL_PIN(159, "GPIO_159"),
+	PINCTRL_PIN(160, "GPIO_160"),
+	PINCTRL_PIN(161, "GPIO_161"),
+	PINCTRL_PIN(162, "GPIO_162"),
+	PINCTRL_PIN(163, "GPIO_163"),
+	PINCTRL_PIN(164, "GPIO_164"),
+	PINCTRL_PIN(165, "GPIO_165"),
+	PINCTRL_PIN(166, "GPIO_166"),
+	PINCTRL_PIN(167, "GPIO_167"),
+	PINCTRL_PIN(168, "GPIO_168"),
+	PINCTRL_PIN(169, "GPIO_169"),
+	PINCTRL_PIN(170, "GPIO_170"),
+	PINCTRL_PIN(171, "GPIO_171"),
+	PINCTRL_PIN(172, "GPIO_172"),
+	PINCTRL_PIN(173, "GPIO_173"),
+	PINCTRL_PIN(174, "GPIO_174"),
+	PINCTRL_PIN(175, "GPIO_175"),
+	PINCTRL_PIN(176, "GPIO_176"),
+	PINCTRL_PIN(177, "GPIO_177"),
+	PINCTRL_PIN(178, "GPIO_178"),
+	PINCTRL_PIN(179, "GPIO_179"),
+	PINCTRL_PIN(180, "GPIO_180"),
+	PINCTRL_PIN(181, "GPIO_181"),
+	PINCTRL_PIN(182, "GPIO_182"),
+	PINCTRL_PIN(183, "GPIO_183"),
+	PINCTRL_PIN(184, "GPIO_184"),
+	PINCTRL_PIN(185, "GPIO_185"),
+	PINCTRL_PIN(186, "GPIO_186"),
+	PINCTRL_PIN(187, "GPIO_187"),
+	PINCTRL_PIN(188, "GPIO_188"),
+	PINCTRL_PIN(189, "GPIO_189"),
+	PINCTRL_PIN(190, "GPIO_190"),
+	PINCTRL_PIN(191, "GPIO_191"),
+	PINCTRL_PIN(192, "GPIO_192"),
+	PINCTRL_PIN(193, "GPIO_193"),
+	PINCTRL_PIN(194, "GPIO_194"),
+	PINCTRL_PIN(195, "GPIO_195"),
+	PINCTRL_PIN(196, "GPIO_196"),
+	PINCTRL_PIN(197, "GPIO_197"),
+	PINCTRL_PIN(198, "GPIO_198"),
+	PINCTRL_PIN(199, "GPIO_199"),
+	PINCTRL_PIN(200, "GPIO_200"),
+	PINCTRL_PIN(201, "GPIO_201"),
+	PINCTRL_PIN(202, "GPIO_202"),
+	PINCTRL_PIN(203, "GPIO_203"),
+	PINCTRL_PIN(204, "GPIO_204"),
+	PINCTRL_PIN(205, "GPIO_205"),
+	PINCTRL_PIN(206, "GPIO_206"),
+	PINCTRL_PIN(207, "GPIO_207"),
+	PINCTRL_PIN(208, "GPIO_208"),
+	PINCTRL_PIN(209, "GPIO_209"),
+	PINCTRL_PIN(210, "GPIO_210"),
+	PINCTRL_PIN(211, "GPIO_211"),
+	PINCTRL_PIN(212, "GPIO_212"),
+	PINCTRL_PIN(213, "GPIO_213"),
+	PINCTRL_PIN(214, "GPIO_214"),
+	PINCTRL_PIN(215, "GPIO_215"),
+	PINCTRL_PIN(216, "GPIO_216"),
+	PINCTRL_PIN(217, "GPIO_217"),
+	PINCTRL_PIN(218, "GPIO_218"),
+	PINCTRL_PIN(219, "GPIO_219"),
+	PINCTRL_PIN(220, "GPIO_220"),
+	PINCTRL_PIN(221, "GPIO_221"),
+	PINCTRL_PIN(222, "GPIO_222"),
+	PINCTRL_PIN(223, "GPIO_223"),
+	PINCTRL_PIN(224, "GPIO_224"),
+	PINCTRL_PIN(225, "GPIO_225"),
+	PINCTRL_PIN(226, "UFS_RESET"),
+	PINCTRL_PIN(227, "SDC2_CLK"),
+	PINCTRL_PIN(228, "SDC2_CMD"),
+	PINCTRL_PIN(229, "SDC2_DATA"),
+};
+
+#define DECLARE_MSM_GPIO_PINS(pin) \
+	static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_MSM_GPIO_PINS(0);
+DECLARE_MSM_GPIO_PINS(1);
+DECLARE_MSM_GPIO_PINS(2);
+DECLARE_MSM_GPIO_PINS(3);
+DECLARE_MSM_GPIO_PINS(4);
+DECLARE_MSM_GPIO_PINS(5);
+DECLARE_MSM_GPIO_PINS(6);
+DECLARE_MSM_GPIO_PINS(7);
+DECLARE_MSM_GPIO_PINS(8);
+DECLARE_MSM_GPIO_PINS(9);
+DECLARE_MSM_GPIO_PINS(10);
+DECLARE_MSM_GPIO_PINS(11);
+DECLARE_MSM_GPIO_PINS(12);
+DECLARE_MSM_GPIO_PINS(13);
+DECLARE_MSM_GPIO_PINS(14);
+DECLARE_MSM_GPIO_PINS(15);
+DECLARE_MSM_GPIO_PINS(16);
+DECLARE_MSM_GPIO_PINS(17);
+DECLARE_MSM_GPIO_PINS(18);
+DECLARE_MSM_GPIO_PINS(19);
+DECLARE_MSM_GPIO_PINS(20);
+DECLARE_MSM_GPIO_PINS(21);
+DECLARE_MSM_GPIO_PINS(22);
+DECLARE_MSM_GPIO_PINS(23);
+DECLARE_MSM_GPIO_PINS(24);
+DECLARE_MSM_GPIO_PINS(25);
+DECLARE_MSM_GPIO_PINS(26);
+DECLARE_MSM_GPIO_PINS(27);
+DECLARE_MSM_GPIO_PINS(28);
+DECLARE_MSM_GPIO_PINS(29);
+DECLARE_MSM_GPIO_PINS(30);
+DECLARE_MSM_GPIO_PINS(31);
+DECLARE_MSM_GPIO_PINS(32);
+DECLARE_MSM_GPIO_PINS(33);
+DECLARE_MSM_GPIO_PINS(34);
+DECLARE_MSM_GPIO_PINS(35);
+DECLARE_MSM_GPIO_PINS(36);
+DECLARE_MSM_GPIO_PINS(37);
+DECLARE_MSM_GPIO_PINS(38);
+DECLARE_MSM_GPIO_PINS(39);
+DECLARE_MSM_GPIO_PINS(40);
+DECLARE_MSM_GPIO_PINS(41);
+DECLARE_MSM_GPIO_PINS(42);
+DECLARE_MSM_GPIO_PINS(43);
+DECLARE_MSM_GPIO_PINS(44);
+DECLARE_MSM_GPIO_PINS(45);
+DECLARE_MSM_GPIO_PINS(46);
+DECLARE_MSM_GPIO_PINS(47);
+DECLARE_MSM_GPIO_PINS(48);
+DECLARE_MSM_GPIO_PINS(49);
+DECLARE_MSM_GPIO_PINS(50);
+DECLARE_MSM_GPIO_PINS(51);
+DECLARE_MSM_GPIO_PINS(52);
+DECLARE_MSM_GPIO_PINS(53);
+DECLARE_MSM_GPIO_PINS(54);
+DECLARE_MSM_GPIO_PINS(55);
+DECLARE_MSM_GPIO_PINS(56);
+DECLARE_MSM_GPIO_PINS(57);
+DECLARE_MSM_GPIO_PINS(58);
+DECLARE_MSM_GPIO_PINS(59);
+DECLARE_MSM_GPIO_PINS(60);
+DECLARE_MSM_GPIO_PINS(61);
+DECLARE_MSM_GPIO_PINS(62);
+DECLARE_MSM_GPIO_PINS(63);
+DECLARE_MSM_GPIO_PINS(64);
+DECLARE_MSM_GPIO_PINS(65);
+DECLARE_MSM_GPIO_PINS(66);
+DECLARE_MSM_GPIO_PINS(67);
+DECLARE_MSM_GPIO_PINS(68);
+DECLARE_MSM_GPIO_PINS(69);
+DECLARE_MSM_GPIO_PINS(70);
+DECLARE_MSM_GPIO_PINS(71);
+DECLARE_MSM_GPIO_PINS(72);
+DECLARE_MSM_GPIO_PINS(73);
+DECLARE_MSM_GPIO_PINS(74);
+DECLARE_MSM_GPIO_PINS(75);
+DECLARE_MSM_GPIO_PINS(76);
+DECLARE_MSM_GPIO_PINS(77);
+DECLARE_MSM_GPIO_PINS(78);
+DECLARE_MSM_GPIO_PINS(79);
+DECLARE_MSM_GPIO_PINS(80);
+DECLARE_MSM_GPIO_PINS(81);
+DECLARE_MSM_GPIO_PINS(82);
+DECLARE_MSM_GPIO_PINS(83);
+DECLARE_MSM_GPIO_PINS(84);
+DECLARE_MSM_GPIO_PINS(85);
+DECLARE_MSM_GPIO_PINS(86);
+DECLARE_MSM_GPIO_PINS(87);
+DECLARE_MSM_GPIO_PINS(88);
+DECLARE_MSM_GPIO_PINS(89);
+DECLARE_MSM_GPIO_PINS(90);
+DECLARE_MSM_GPIO_PINS(91);
+DECLARE_MSM_GPIO_PINS(92);
+DECLARE_MSM_GPIO_PINS(93);
+DECLARE_MSM_GPIO_PINS(94);
+DECLARE_MSM_GPIO_PINS(95);
+DECLARE_MSM_GPIO_PINS(96);
+DECLARE_MSM_GPIO_PINS(97);
+DECLARE_MSM_GPIO_PINS(98);
+DECLARE_MSM_GPIO_PINS(99);
+DECLARE_MSM_GPIO_PINS(100);
+DECLARE_MSM_GPIO_PINS(101);
+DECLARE_MSM_GPIO_PINS(102);
+DECLARE_MSM_GPIO_PINS(103);
+DECLARE_MSM_GPIO_PINS(104);
+DECLARE_MSM_GPIO_PINS(105);
+DECLARE_MSM_GPIO_PINS(106);
+DECLARE_MSM_GPIO_PINS(107);
+DECLARE_MSM_GPIO_PINS(108);
+DECLARE_MSM_GPIO_PINS(109);
+DECLARE_MSM_GPIO_PINS(110);
+DECLARE_MSM_GPIO_PINS(111);
+DECLARE_MSM_GPIO_PINS(112);
+DECLARE_MSM_GPIO_PINS(113);
+DECLARE_MSM_GPIO_PINS(114);
+DECLARE_MSM_GPIO_PINS(115);
+DECLARE_MSM_GPIO_PINS(116);
+DECLARE_MSM_GPIO_PINS(117);
+DECLARE_MSM_GPIO_PINS(118);
+DECLARE_MSM_GPIO_PINS(119);
+DECLARE_MSM_GPIO_PINS(120);
+DECLARE_MSM_GPIO_PINS(121);
+DECLARE_MSM_GPIO_PINS(122);
+DECLARE_MSM_GPIO_PINS(123);
+DECLARE_MSM_GPIO_PINS(124);
+DECLARE_MSM_GPIO_PINS(125);
+DECLARE_MSM_GPIO_PINS(126);
+DECLARE_MSM_GPIO_PINS(127);
+DECLARE_MSM_GPIO_PINS(128);
+DECLARE_MSM_GPIO_PINS(129);
+DECLARE_MSM_GPIO_PINS(130);
+DECLARE_MSM_GPIO_PINS(131);
+DECLARE_MSM_GPIO_PINS(132);
+DECLARE_MSM_GPIO_PINS(133);
+DECLARE_MSM_GPIO_PINS(134);
+DECLARE_MSM_GPIO_PINS(135);
+DECLARE_MSM_GPIO_PINS(136);
+DECLARE_MSM_GPIO_PINS(137);
+DECLARE_MSM_GPIO_PINS(138);
+DECLARE_MSM_GPIO_PINS(139);
+DECLARE_MSM_GPIO_PINS(140);
+DECLARE_MSM_GPIO_PINS(141);
+DECLARE_MSM_GPIO_PINS(142);
+DECLARE_MSM_GPIO_PINS(143);
+DECLARE_MSM_GPIO_PINS(144);
+DECLARE_MSM_GPIO_PINS(145);
+DECLARE_MSM_GPIO_PINS(146);
+DECLARE_MSM_GPIO_PINS(147);
+DECLARE_MSM_GPIO_PINS(148);
+DECLARE_MSM_GPIO_PINS(149);
+DECLARE_MSM_GPIO_PINS(150);
+DECLARE_MSM_GPIO_PINS(151);
+DECLARE_MSM_GPIO_PINS(152);
+DECLARE_MSM_GPIO_PINS(153);
+DECLARE_MSM_GPIO_PINS(154);
+DECLARE_MSM_GPIO_PINS(155);
+DECLARE_MSM_GPIO_PINS(156);
+DECLARE_MSM_GPIO_PINS(157);
+DECLARE_MSM_GPIO_PINS(158);
+DECLARE_MSM_GPIO_PINS(159);
+DECLARE_MSM_GPIO_PINS(160);
+DECLARE_MSM_GPIO_PINS(161);
+DECLARE_MSM_GPIO_PINS(162);
+DECLARE_MSM_GPIO_PINS(163);
+DECLARE_MSM_GPIO_PINS(164);
+DECLARE_MSM_GPIO_PINS(165);
+DECLARE_MSM_GPIO_PINS(166);
+DECLARE_MSM_GPIO_PINS(167);
+DECLARE_MSM_GPIO_PINS(168);
+DECLARE_MSM_GPIO_PINS(169);
+DECLARE_MSM_GPIO_PINS(170);
+DECLARE_MSM_GPIO_PINS(171);
+DECLARE_MSM_GPIO_PINS(172);
+DECLARE_MSM_GPIO_PINS(173);
+DECLARE_MSM_GPIO_PINS(174);
+DECLARE_MSM_GPIO_PINS(175);
+DECLARE_MSM_GPIO_PINS(176);
+DECLARE_MSM_GPIO_PINS(177);
+DECLARE_MSM_GPIO_PINS(178);
+DECLARE_MSM_GPIO_PINS(179);
+DECLARE_MSM_GPIO_PINS(180);
+DECLARE_MSM_GPIO_PINS(181);
+DECLARE_MSM_GPIO_PINS(182);
+DECLARE_MSM_GPIO_PINS(183);
+DECLARE_MSM_GPIO_PINS(184);
+DECLARE_MSM_GPIO_PINS(185);
+DECLARE_MSM_GPIO_PINS(186);
+DECLARE_MSM_GPIO_PINS(187);
+DECLARE_MSM_GPIO_PINS(188);
+DECLARE_MSM_GPIO_PINS(189);
+DECLARE_MSM_GPIO_PINS(190);
+DECLARE_MSM_GPIO_PINS(191);
+DECLARE_MSM_GPIO_PINS(192);
+DECLARE_MSM_GPIO_PINS(193);
+DECLARE_MSM_GPIO_PINS(194);
+DECLARE_MSM_GPIO_PINS(195);
+DECLARE_MSM_GPIO_PINS(196);
+DECLARE_MSM_GPIO_PINS(197);
+DECLARE_MSM_GPIO_PINS(198);
+DECLARE_MSM_GPIO_PINS(199);
+DECLARE_MSM_GPIO_PINS(200);
+DECLARE_MSM_GPIO_PINS(201);
+DECLARE_MSM_GPIO_PINS(202);
+DECLARE_MSM_GPIO_PINS(203);
+DECLARE_MSM_GPIO_PINS(204);
+DECLARE_MSM_GPIO_PINS(205);
+DECLARE_MSM_GPIO_PINS(206);
+DECLARE_MSM_GPIO_PINS(207);
+DECLARE_MSM_GPIO_PINS(208);
+DECLARE_MSM_GPIO_PINS(209);
+DECLARE_MSM_GPIO_PINS(210);
+DECLARE_MSM_GPIO_PINS(211);
+DECLARE_MSM_GPIO_PINS(212);
+DECLARE_MSM_GPIO_PINS(213);
+DECLARE_MSM_GPIO_PINS(214);
+DECLARE_MSM_GPIO_PINS(215);
+DECLARE_MSM_GPIO_PINS(216);
+DECLARE_MSM_GPIO_PINS(217);
+DECLARE_MSM_GPIO_PINS(218);
+DECLARE_MSM_GPIO_PINS(219);
+DECLARE_MSM_GPIO_PINS(220);
+DECLARE_MSM_GPIO_PINS(221);
+DECLARE_MSM_GPIO_PINS(222);
+DECLARE_MSM_GPIO_PINS(223);
+DECLARE_MSM_GPIO_PINS(224);
+DECLARE_MSM_GPIO_PINS(225);
+
+static const unsigned int ufs_reset_pins[] = { 226 };
+static const unsigned int sdc2_clk_pins[] = { 227 };
+static const unsigned int sdc2_cmd_pins[] = { 228 };
+static const unsigned int sdc2_data_pins[] = { 229 };
+
+enum hawi_functions {
+	msm_mux_gpio,
+	msm_mux_aoss_cti,
+	msm_mux_atest_char,
+	msm_mux_atest_usb,
+	msm_mux_audio_ext_mclk,
+	msm_mux_audio_ref_clk,
+	msm_mux_cam_mclk,
+	msm_mux_cci_async_in,
+	msm_mux_cci_i2c0,
+	msm_mux_cci_i2c1,
+	msm_mux_cci_i2c2,
+	msm_mux_cci_i2c3,
+	msm_mux_cci_i2c4,
+	msm_mux_cci_i2c5,
+	msm_mux_cci_timer,
+	msm_mux_coex_espmi,
+	msm_mux_coex_uart1_rx,
+	msm_mux_coex_uart1_tx,
+	msm_mux_dbg_out_clk,
+	msm_mux_ddr_bist,
+	msm_mux_ddr_pxi,
+	msm_mux_dp_hot,
+	msm_mux_egpio,
+	msm_mux_gcc_gp,
+	msm_mux_gnss_adc,
+	msm_mux_host_rst,
+	msm_mux_i2chub0_se0,
+	msm_mux_i2chub0_se1,
+	msm_mux_i2chub0_se2,
+	msm_mux_i2chub0_se3,
+	msm_mux_i2chub0_se4,
+	msm_mux_i2s0,
+	msm_mux_i2s1,
+	msm_mux_ibi_i3c,
+	msm_mux_jitter_bist,
+	msm_mux_mdp_esync0,
+	msm_mux_mdp_esync1,
+	msm_mux_mdp_esync2,
+	msm_mux_mdp_vsync,
+	msm_mux_mdp_vsync_e,
+	msm_mux_mdp_vsync_p,
+	msm_mux_mdp_vsync0_out,
+	msm_mux_mdp_vsync1_out,
+	msm_mux_mdp_vsync2_out,
+	msm_mux_mdp_vsync3_out,
+	msm_mux_mdp_vsync5_out,
+	msm_mux_modem_pps_in,
+	msm_mux_modem_pps_out,
+	msm_mux_nav_gpio,
+	msm_mux_nav_gpio0,
+	msm_mux_nav_gpio3,
+	msm_mux_nav_rffe,
+	msm_mux_pcie0_clk_req_n,
+	msm_mux_pcie0_rst_n,
+	msm_mux_pcie1_clk_req_n,
+	msm_mux_phase_flag,
+	msm_mux_pll_bist_sync,
+	msm_mux_pll_clk_aux,
+	msm_mux_qdss_cti,
+	msm_mux_qlink,
+	msm_mux_qspi,
+	msm_mux_qspi_clk,
+	msm_mux_qspi_cs,
+	msm_mux_qup1_se0,
+	msm_mux_qup1_se1,
+	msm_mux_qup1_se2,
+	msm_mux_qup1_se3,
+	msm_mux_qup1_se4,
+	msm_mux_qup1_se5,
+	msm_mux_qup1_se6,
+	msm_mux_qup1_se7,
+	msm_mux_qup2_se0,
+	msm_mux_qup2_se1,
+	msm_mux_qup2_se2,
+	msm_mux_qup2_se3,
+	msm_mux_qup2_se4_01,
+	msm_mux_qup2_se4_23,
+	msm_mux_qup3_se0_01,
+	msm_mux_qup3_se0_23,
+	msm_mux_qup3_se1,
+	msm_mux_qup3_se2,
+	msm_mux_qup3_se3,
+	msm_mux_qup3_se4,
+	msm_mux_qup3_se5,
+	msm_mux_qup4_se0,
+	msm_mux_qup4_se1,
+	msm_mux_qup4_se2,
+	msm_mux_qup4_se3_01,
+	msm_mux_qup4_se3_23,
+	msm_mux_qup4_se3_l3,
+	msm_mux_qup4_se4_01,
+	msm_mux_qup4_se4_23,
+	msm_mux_qup4_se4_l3,
+	msm_mux_rng_rosc,
+	msm_mux_sd_write_protect,
+	msm_mux_sdc4_clk,
+	msm_mux_sdc4_cmd,
+	msm_mux_sdc4_data,
+	msm_mux_sys_throttle,
+	msm_mux_tb_trig_sdc,
+	msm_mux_tmess_rng,
+	msm_mux_tsense_clm,
+	msm_mux_tsense_pwm,
+	msm_mux_uim0,
+	msm_mux_uim1,
+	msm_mux_usb0_hs,
+	msm_mux_usb_phy,
+	msm_mux_vfr,
+	msm_mux_vsense_trigger_mirnat,
+	msm_mux_wcn_sw_ctrl,
+	msm_mux__,
+};
+
+static const char *const gpio_groups[] = {
+	"gpio0",   "gpio1",   "gpio2",   "gpio3",   "gpio4",   "gpio5",
+	"gpio6",   "gpio7",   "gpio8",   "gpio9",   "gpio10",  "gpio11",
+	"gpio12",  "gpio13",  "gpio14",  "gpio15",  "gpio16",  "gpio17",
+	"gpio18",  "gpio19",  "gpio20",  "gpio21",  "gpio22",  "gpio23",
+	"gpio24",  "gpio25",  "gpio26",  "gpio27",  "gpio28",  "gpio29",
+	"gpio30",  "gpio31",  "gpio32",  "gpio33",  "gpio34",  "gpio35",
+	"gpio36",  "gpio37",  "gpio38",  "gpio39",  "gpio40",  "gpio41",
+	"gpio42",  "gpio43",  "gpio44",  "gpio45",  "gpio46",  "gpio47",
+	"gpio48",  "gpio49",  "gpio50",  "gpio51",  "gpio52",  "gpio53",
+	"gpio54",  "gpio55",  "gpio56",  "gpio57",  "gpio58",  "gpio59",
+	"gpio60",  "gpio61",  "gpio62",  "gpio63",  "gpio64",  "gpio65",
+	"gpio66",  "gpio67",  "gpio68",  "gpio69",  "gpio70",  "gpio71",
+	"gpio72",  "gpio73",  "gpio74",  "gpio75",  "gpio76",  "gpio77",
+	"gpio78",  "gpio79",  "gpio80",  "gpio81",  "gpio82",  "gpio83",
+	"gpio84",  "gpio85",  "gpio86",  "gpio87",  "gpio88",  "gpio89",
+	"gpio90",  "gpio91",  "gpio92",  "gpio93",  "gpio94",  "gpio95",
+	"gpio96",  "gpio97",  "gpio98",  "gpio99",  "gpio100", "gpio101",
+	"gpio102", "gpio103", "gpio104", "gpio105", "gpio106", "gpio107",
+	"gpio108", "gpio109", "gpio110", "gpio111", "gpio112", "gpio113",
+	"gpio114", "gpio115", "gpio116", "gpio117", "gpio118", "gpio119",
+	"gpio120", "gpio121", "gpio122", "gpio123", "gpio124", "gpio125",
+	"gpio126", "gpio127", "gpio128", "gpio129", "gpio130", "gpio131",
+	"gpio132", "gpio133", "gpio134", "gpio135", "gpio136", "gpio137",
+	"gpio138", "gpio139", "gpio140", "gpio141", "gpio142", "gpio143",
+	"gpio144", "gpio145", "gpio146", "gpio147", "gpio148", "gpio149",
+	"gpio150", "gpio151", "gpio152", "gpio153", "gpio154", "gpio155",
+	"gpio156", "gpio157", "gpio158", "gpio159", "gpio160", "gpio161",
+	"gpio162", "gpio163", "gpio164", "gpio165", "gpio166", "gpio167",
+	"gpio168", "gpio169", "gpio170", "gpio171", "gpio172", "gpio173",
+	"gpio174", "gpio175", "gpio176", "gpio177", "gpio178", "gpio179",
+	"gpio180", "gpio181", "gpio182", "gpio183", "gpio184", "gpio185",
+	"gpio186", "gpio187", "gpio188", "gpio189", "gpio190", "gpio191",
+	"gpio192", "gpio193", "gpio194", "gpio195", "gpio196", "gpio197",
+	"gpio198", "gpio199", "gpio200", "gpio201", "gpio202", "gpio203",
+	"gpio204", "gpio205", "gpio206", "gpio207", "gpio208", "gpio209",
+	"gpio210", "gpio211", "gpio212", "gpio213", "gpio214", "gpio215",
+	"gpio216", "gpio217", "gpio218", "gpio219", "gpio220", "gpio221",
+	"gpio222", "gpio223", "gpio224", "gpio225",
+};
+
+static const char *const aoss_cti_groups[] = {
+	"gpio74", "gpio75", "gpio76", "gpio77",
+};
+
+static const char *const atest_char_groups[] = {
+	"gpio126", "gpio127", "gpio128", "gpio129", "gpio133",
+};
+
+static const char *const atest_usb_groups[] = {
+	"gpio70", "gpio71", "gpio72", "gpio73", "gpio129",
+};
+
+static const char *const audio_ext_mclk_groups[] = {
+	"gpio120", "gpio121",
+};
+
+static const char *const audio_ref_clk_groups[] = {
+	"gpio120",
+};
+
+static const char *const cam_mclk_groups[] = {
+	"gpio89", "gpio90", "gpio91", "gpio92", "gpio93", "gpio94",
+	"gpio95", "gpio96",
+};
+
+static const char *const cci_async_in_groups[] = {
+	"gpio15", "gpio109", "gpio110",
+};
+
+static const char *const cci_i2c0_groups[] = {
+	"gpio109", "gpio110",
+};
+
+static const char *const cci_i2c1_groups[] = {
+	"gpio111", "gpio112",
+};
+
+static const char *const cci_i2c2_groups[] = {
+	"gpio113", "gpio114",
+};
+
+static const char *const cci_i2c3_groups[] = {
+	"gpio107", "gpio160",
+};
+
+static const char *const cci_i2c4_groups[] = {
+	"gpio108", "gpio149",
+};
+
+static const char *const cci_i2c5_groups[] = {
+	"gpio115", "gpio116",
+};
+
+static const char *const cci_timer_groups[] = {
+	"gpio105", "gpio106", "gpio107", "gpio159", "gpio160",
+};
+
+static const char *const coex_espmi_groups[] = {
+	"gpio144", "gpio145",
+};
+
+static const char *const coex_uart1_rx_groups[] = {
+	"gpio144",
+};
+
+static const char *const coex_uart1_tx_groups[] = {
+	"gpio145",
+};
+
+static const char *const dbg_out_clk_groups[] = {
+	"gpio82",
+};
+
+static const char *const ddr_bist_groups[] = {
+	"gpio40", "gpio41", "gpio44", "gpio45",
+};
+
+static const char *const ddr_pxi_groups[] = {
+	"gpio43", "gpio44", "gpio45", "gpio46",
+	"gpio52", "gpio53", "gpio54", "gpio55",
+};
+
+static const char *const dp_hot_groups[] = {
+	"gpio47",
+};
+
+static const char *const egpio_groups[] = {
+	"gpio0",   "gpio1",   "gpio2",   "gpio3",   "gpio4",   "gpio5",
+	"gpio6",   "gpio7",   "gpio28",  "gpio29",  "gpio30",  "gpio31",
+	"gpio48",  "gpio49",  "gpio50",  "gpio51",  "gpio163", "gpio164",
+	"gpio165", "gpio166", "gpio167", "gpio168", "gpio169", "gpio170",
+	"gpio171", "gpio172", "gpio173", "gpio174", "gpio175", "gpio176",
+	"gpio177", "gpio178", "gpio179", "gpio180", "gpio181", "gpio182",
+	"gpio183", "gpio184", "gpio185", "gpio186", "gpio187", "gpio188",
+	"gpio189", "gpio190", "gpio191", "gpio192", "gpio193", "gpio194",
+	"gpio195", "gpio196", "gpio197", "gpio198", "gpio199", "gpio200",
+	"gpio201", "gpio202", "gpio203", "gpio204", "gpio205", "gpio206",
+	"gpio207", "gpio208", "gpio209", "gpio212", "gpio213", "gpio214",
+	"gpio215", "gpio216", "gpio217", "gpio218",
+};
+
+static const char *const gcc_gp_groups[] = {
+	"gpio86", "gpio87", "gpio130", "gpio131", "gpio132", "gpio158",
+};
+
+static const char *const gnss_adc_groups[] = {
+	"gpio40", "gpio41", "gpio42", "gpio77",
+};
+
+static const char *const host_rst_groups[] = {
+	"gpio106",
+};
+
+static const char *const i2chub0_se0_groups[] = {
+	"gpio66", "gpio67",
+};
+
+static const char *const i2chub0_se1_groups[] = {
+	"gpio78", "gpio79",
+};
+
+static const char *const i2chub0_se2_groups[] = {
+	"gpio68", "gpio69",
+};
+
+static const char *const i2chub0_se3_groups[] = {
+	"gpio70", "gpio71",
+};
+
+static const char *const i2chub0_se4_groups[] = {
+	"gpio72", "gpio73",
+};
+
+static const char *const i2s0_groups[] = {
+	"gpio122", "gpio123", "gpio124", "gpio125",
+};
+
+static const char *const i2s1_groups[] = {
+	"gpio117", "gpio118", "gpio119", "gpio120",
+};
+
+static const char *const ibi_i3c_groups[] = {
+	"gpio0",  "gpio1",  "gpio4",  "gpio5",  "gpio8",  "gpio9",
+	"gpio12", "gpio13", "gpio28", "gpio29", "gpio32", "gpio33",
+	"gpio36", "gpio37", "gpio48", "gpio49", "gpio60", "gpio61",
+};
+
+static const char *const jitter_bist_groups[] = {
+	"gpio73",
+};
+
+static const char *const mdp_esync0_groups[] = {
+	"gpio88", "gpio100",
+};
+
+static const char *const mdp_esync1_groups[] = {
+	"gpio86", "gpio100",
+};
+
+static const char *const mdp_esync2_groups[] = {
+	"gpio87", "gpio97",
+};
+
+static const char *const mdp_vsync_groups[] = {
+	"gpio86", "gpio87", "gpio88", "gpio97",
+};
+
+static const char *const mdp_vsync_e_groups[] = {
+	"gpio98",
+};
+
+static const char *const mdp_vsync_p_groups[] = {
+	"gpio98",
+};
+
+static const char *const mdp_vsync0_out_groups[] = {
+	"gpio86",
+};
+
+static const char *const mdp_vsync1_out_groups[] = {
+	"gpio86",
+};
+
+static const char *const mdp_vsync2_out_groups[] = {
+	"gpio87",
+};
+
+static const char *const mdp_vsync3_out_groups[] = {
+	"gpio87",
+};
+
+static const char *const mdp_vsync5_out_groups[] = {
+	"gpio87",
+};
+
+static const char *const modem_pps_in_groups[] = {
+	"gpio151",
+};
+
+static const char *const modem_pps_out_groups[] = {
+	"gpio151",
+};
+
+static const char *const nav_gpio_groups[] = {
+	"gpio146", "gpio147", "gpio148", "gpio151",
+};
+
+static const char *const nav_gpio0_groups[] = {
+	"gpio150",
+};
+
+static const char *const nav_gpio3_groups[] = {
+	"gpio150",
+};
+
+static const char *const nav_rffe_groups[] = {
+	"gpio134", "gpio135", "gpio138", "gpio139",
+};
+
+static const char *const pcie0_clk_req_n_groups[] = {
+	"gpio103",
+};
+
+static const char *const pcie0_rst_n_groups[] = {
+	"gpio102",
+};
+
+static const char *const pcie1_clk_req_n_groups[] = {
+	"gpio221",
+};
+
+static const char *const phase_flag_groups[] = {
+	"gpio117", "gpio118", "gpio119", "gpio123", "gpio124", "gpio125",
+	"gpio169", "gpio170", "gpio171", "gpio172", "gpio173", "gpio175",
+	"gpio176", "gpio179", "gpio180", "gpio181", "gpio184", "gpio185",
+	"gpio192", "gpio196", "gpio197", "gpio198", "gpio199", "gpio204",
+	"gpio206", "gpio207", "gpio208", "gpio210", "gpio211", "gpio214",
+	"gpio215", "gpio216",
+};
+
+static const char *const pll_bist_sync_groups[] = {
+	"gpio104",
+};
+
+static const char *const pll_clk_aux_groups[] = {
+	"gpio94",
+};
+
+static const char *const qdss_cti_groups[] = {
+	"gpio27",  "gpio31", "gpio72", "gpio73", "gpio82", "gpio83",
+	"gpio152", "gpio158",
+};
+
+static const char *const qlink_groups[] = {
+	"gpio152", "gpio153", "gpio154",
+};
+
+static const char *const qspi_groups[] = {
+	"gpio80", "gpio81", "gpio82", "gpio147",
+};
+
+static const char *const qspi_clk_groups[] = {
+	"gpio83",
+};
+
+static const char *const qspi_cs_groups[] = {
+	"gpio146", "gpio148",
+};
+
+static const char *const qup1_se0_groups[] = {
+	"gpio80", "gpio81", "gpio82", "gpio83",
+};
+
+static const char *const qup1_se1_groups[] = {
+	"gpio74", "gpio75", "gpio76", "gpio77",
+};
+
+static const char *const qup1_se2_groups[] = {
+	"gpio40", "gpio41", "gpio42", "gpio43", "gpio130", "gpio131", "gpio132",
+};
+
+static const char *const qup1_se3_groups[] = {
+	"gpio44", "gpio45", "gpio46", "gpio47",
+};
+
+static const char *const qup1_se4_groups[] = {
+	"gpio36", "gpio37", "gpio38", "gpio39",
+};
+
+static const char *const qup1_se5_groups[] = {
+	"gpio52", "gpio53", "gpio54", "gpio55",
+};
+
+static const char *const qup1_se6_groups[] = {
+	"gpio56", "gpio57", "gpio58", "gpio59",
+};
+
+static const char *const qup1_se7_groups[] = {
+	"gpio60", "gpio61", "gpio62", "gpio63",
+};
+
+static const char *const qup2_se0_groups[] = {
+	"gpio0", "gpio1", "gpio2", "gpio3",
+};
+
+static const char *const qup2_se1_groups[] = {
+	"gpio4", "gpio5", "gpio6", "gpio7",
+};
+
+static const char *const qup2_se2_groups[] = {
+	"gpio117", "gpio118", "gpio119", "gpio120",
+};
+
+static const char *const qup2_se3_groups[] = {
+	"gpio97", "gpio122", "gpio123", "gpio124", "gpio125",
+};
+
+static const char *const qup2_se4_01_groups[] = {
+	"gpio208", "gpio209",
+};
+
+static const char *const qup2_se4_23_groups[] = {
+	"gpio208", "gpio209",
+};
+
+static const char *const qup3_se0_01_groups[] = {
+	"gpio64", "gpio65",
+};
+
+static const char *const qup3_se0_23_groups[] = {
+	"gpio64", "gpio65",
+};
+
+static const char *const qup3_se1_groups[] = {
+	"gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio15",
+};
+
+static const char *const qup3_se2_groups[] = {
+	"gpio12", "gpio13", "gpio14", "gpio15",
+};
+
+static const char *const qup3_se3_groups[] = {
+	"gpio16", "gpio17", "gpio18", "gpio19",
+};
+
+static const char *const qup3_se4_groups[] = {
+	"gpio20", "gpio21", "gpio22", "gpio23",
+};
+
+static const char *const qup3_se5_groups[] = {
+	"gpio24", "gpio25", "gpio26", "gpio27",
+};
+
+static const char *const qup4_se0_groups[] = {
+	"gpio48", "gpio49", "gpio50", "gpio51",
+};
+
+static const char *const qup4_se1_groups[] = {
+	"gpio28", "gpio29", "gpio30", "gpio31",
+};
+
+static const char *const qup4_se2_groups[] = {
+	"gpio32", "gpio33", "gpio34", "gpio35",
+};
+
+static const char *const qup4_se3_01_groups[] = {
+	"gpio84", "gpio121",
+};
+
+static const char *const qup4_se3_23_groups[] = {
+	"gpio84", "gpio121",
+};
+
+static const char *const qup4_se3_l3_groups[] = {
+	"gpio98",
+};
+
+static const char *const qup4_se4_01_groups[] = {
+	"gpio161", "gpio162",
+};
+
+static const char *const qup4_se4_23_groups[] = {
+	"gpio161", "gpio162",
+};
+
+static const char *const qup4_se4_l3_groups[] = {
+	"gpio88",
+};
+
+static const char *const rng_rosc_groups[] = {
+	"gpio64", "gpio65", "gpio66", "gpio84",
+};
+
+static const char *const sd_write_protect_groups[] = {
+	"gpio85",
+};
+
+static const char *const sdc4_clk_groups[] = {
+	"gpio83",
+};
+
+static const char *const sdc4_cmd_groups[] = {
+	"gpio148",
+};
+
+static const char *const sdc4_data_groups[] = {
+	"gpio80", "gpio81", "gpio82", "gpio147",
+};
+
+static const char *const sys_throttle_groups[] = {
+	"gpio99",
+};
+
+static const char *const tb_trig_sdc_groups[] = {
+	"gpio88", "gpio146",
+};
+
+static const char *const tmess_rng_groups[] = {
+	"gpio64", "gpio65", "gpio66", "gpio84",
+};
+
+static const char *const tsense_clm_groups[] = {
+	"gpio10", "gpio87", "gpio97", "gpio99", "gpio105", "gpio106",
+	"gpio159",
+};
+
+static const char *const tsense_pwm_groups[] = {
+	"gpio10", "gpio87", "gpio97", "gpio99", "gpio223", "gpio224",
+	"gpio225",
+};
+
+static const char *const uim0_groups[] = {
+	"gpio126", "gpio127", "gpio128", "gpio129",
+};
+
+static const char *const uim1_groups[] = {
+	"gpio36", "gpio37", "gpio39", "gpio54", "gpio55", "gpio56",
+	"gpio70", "gpio71", "gpio72", "gpio130", "gpio131", "gpio132",
+	"gpio133",
+};
+
+static const char *const usb0_hs_groups[] = {
+	"gpio79",
+};
+
+static const char *const usb_phy_groups[] = {
+	"gpio59", "gpio60",
+};
+
+static const char *const vfr_groups[] = {
+	"gpio146", "gpio151",
+};
+
+static const char *const vsense_trigger_mirnat_groups[] = {
+	"gpio59",
+};
+
+static const char *const wcn_sw_ctrl_groups[] = {
+	"gpio18", "gpio19", "gpio155", "gpio156",
+};
+
+static const struct pinfunction hawi_functions[] = {
+	MSM_GPIO_PIN_FUNCTION(gpio),
+	MSM_PIN_FUNCTION(aoss_cti),
+	MSM_PIN_FUNCTION(atest_char),
+	MSM_PIN_FUNCTION(atest_usb),
+	MSM_PIN_FUNCTION(audio_ext_mclk),
+	MSM_PIN_FUNCTION(audio_ref_clk),
+	MSM_PIN_FUNCTION(cam_mclk),
+	MSM_PIN_FUNCTION(cci_async_in),
+	MSM_PIN_FUNCTION(cci_i2c0),
+	MSM_PIN_FUNCTION(cci_i2c1),
+	MSM_PIN_FUNCTION(cci_i2c2),
+	MSM_PIN_FUNCTION(cci_i2c3),
+	MSM_PIN_FUNCTION(cci_i2c4),
+	MSM_PIN_FUNCTION(cci_i2c5),
+	MSM_PIN_FUNCTION(cci_timer),
+	MSM_PIN_FUNCTION(coex_espmi),
+	MSM_PIN_FUNCTION(coex_uart1_rx),
+	MSM_PIN_FUNCTION(coex_uart1_tx),
+	MSM_PIN_FUNCTION(dbg_out_clk),
+	MSM_PIN_FUNCTION(ddr_bist),
+	MSM_PIN_FUNCTION(ddr_pxi),
+	MSM_PIN_FUNCTION(dp_hot),
+	MSM_PIN_FUNCTION(egpio),
+	MSM_PIN_FUNCTION(gcc_gp),
+	MSM_PIN_FUNCTION(gnss_adc),
+	MSM_PIN_FUNCTION(host_rst),
+	MSM_PIN_FUNCTION(i2chub0_se0),
+	MSM_PIN_FUNCTION(i2chub0_se1),
+	MSM_PIN_FUNCTION(i2chub0_se2),
+	MSM_PIN_FUNCTION(i2chub0_se3),
+	MSM_PIN_FUNCTION(i2chub0_se4),
+	MSM_PIN_FUNCTION(i2s0),
+	MSM_PIN_FUNCTION(i2s1),
+	MSM_PIN_FUNCTION(ibi_i3c),
+	MSM_PIN_FUNCTION(jitter_bist),
+	MSM_PIN_FUNCTION(mdp_esync0),
+	MSM_PIN_FUNCTION(mdp_esync1),
+	MSM_PIN_FUNCTION(mdp_esync2),
+	MSM_PIN_FUNCTION(mdp_vsync),
+	MSM_PIN_FUNCTION(mdp_vsync_e),
+	MSM_PIN_FUNCTION(mdp_vsync_p),
+	MSM_PIN_FUNCTION(mdp_vsync0_out),
+	MSM_PIN_FUNCTION(mdp_vsync1_out),
+	MSM_PIN_FUNCTION(mdp_vsync2_out),
+	MSM_PIN_FUNCTION(mdp_vsync3_out),
+	MSM_PIN_FUNCTION(mdp_vsync5_out),
+	MSM_PIN_FUNCTION(modem_pps_in),
+	MSM_PIN_FUNCTION(modem_pps_out),
+	MSM_PIN_FUNCTION(nav_gpio),
+	MSM_PIN_FUNCTION(nav_gpio0),
+	MSM_PIN_FUNCTION(nav_gpio3),
+	MSM_PIN_FUNCTION(nav_rffe),
+	MSM_PIN_FUNCTION(pcie0_clk_req_n),
+	MSM_PIN_FUNCTION(pcie0_rst_n),
+	MSM_PIN_FUNCTION(pcie1_clk_req_n),
+	MSM_PIN_FUNCTION(phase_flag),
+	MSM_PIN_FUNCTION(pll_bist_sync),
+	MSM_PIN_FUNCTION(pll_clk_aux),
+	MSM_PIN_FUNCTION(qdss_cti),
+	MSM_PIN_FUNCTION(qlink),
+	MSM_PIN_FUNCTION(qspi),
+	MSM_PIN_FUNCTION(qspi_clk),
+	MSM_PIN_FUNCTION(qspi_cs),
+	MSM_PIN_FUNCTION(qup1_se0),
+	MSM_PIN_FUNCTION(qup1_se1),
+	MSM_PIN_FUNCTION(qup1_se2),
+	MSM_PIN_FUNCTION(qup1_se3),
+	MSM_PIN_FUNCTION(qup1_se4),
+	MSM_PIN_FUNCTION(qup1_se5),
+	MSM_PIN_FUNCTION(qup1_se6),
+	MSM_PIN_FUNCTION(qup1_se7),
+	MSM_PIN_FUNCTION(qup2_se0),
+	MSM_PIN_FUNCTION(qup2_se1),
+	MSM_PIN_FUNCTION(qup2_se2),
+	MSM_PIN_FUNCTION(qup2_se3),
+	MSM_PIN_FUNCTION(qup2_se4_01),
+	MSM_PIN_FUNCTION(qup2_se4_23),
+	MSM_PIN_FUNCTION(qup3_se0_01),
+	MSM_PIN_FUNCTION(qup3_se0_23),
+	MSM_PIN_FUNCTION(qup3_se1),
+	MSM_PIN_FUNCTION(qup3_se2),
+	MSM_PIN_FUNCTION(qup3_se3),
+	MSM_PIN_FUNCTION(qup3_se4),
+	MSM_PIN_FUNCTION(qup3_se5),
+	MSM_PIN_FUNCTION(qup4_se0),
+	MSM_PIN_FUNCTION(qup4_se1),
+	MSM_PIN_FUNCTION(qup4_se2),
+	MSM_PIN_FUNCTION(qup4_se3_01),
+	MSM_PIN_FUNCTION(qup4_se3_23),
+	MSM_PIN_FUNCTION(qup4_se3_l3),
+	MSM_PIN_FUNCTION(qup4_se4_01),
+	MSM_PIN_FUNCTION(qup4_se4_23),
+	MSM_PIN_FUNCTION(qup4_se4_l3),
+	MSM_PIN_FUNCTION(rng_rosc),
+	MSM_PIN_FUNCTION(sd_write_protect),
+	MSM_PIN_FUNCTION(sdc4_clk),
+	MSM_PIN_FUNCTION(sdc4_cmd),
+	MSM_PIN_FUNCTION(sdc4_data),
+	MSM_PIN_FUNCTION(sys_throttle),
+	MSM_PIN_FUNCTION(tb_trig_sdc),
+	MSM_PIN_FUNCTION(tmess_rng),
+	MSM_PIN_FUNCTION(tsense_clm),
+	MSM_PIN_FUNCTION(tsense_pwm),
+	MSM_PIN_FUNCTION(uim0),
+	MSM_PIN_FUNCTION(uim1),
+	MSM_PIN_FUNCTION(usb0_hs),
+	MSM_PIN_FUNCTION(usb_phy),
+	MSM_PIN_FUNCTION(vfr),
+	MSM_PIN_FUNCTION(vsense_trigger_mirnat),
+	MSM_PIN_FUNCTION(wcn_sw_ctrl),
+};
+
+/*
+ * Every pin is maintained as a single group, and missing or non-existing pin
+ * would be maintained as dummy group to synchronize pin group index with
+ * pin descriptor registered with pinctrl core.
+ * Clients would not be able to request these dummy pin groups.
+ */
+static const struct msm_pingroup hawi_groups[] = {
+	[0] = PINGROUP(0, qup2_se0, ibi_i3c, _, _, _, _, _, _, _, _, egpio),
+	[1] = PINGROUP(1, qup2_se0, ibi_i3c, _, _, _, _, _, _, _, _, egpio),
+	[2] = PINGROUP(2, qup2_se0, _, _, _, _, _, _, _, _, _, egpio),
+	[3] = PINGROUP(3, qup2_se0, _, _, _, _, _, _, _, _, _, egpio),
+	[4] = PINGROUP(4, qup2_se1, ibi_i3c, _, _, _, _, _, _, _, _, egpio),
+	[5] = PINGROUP(5, qup2_se1, ibi_i3c, _, _, _, _, _, _, _, _, egpio),
+	[6] = PINGROUP(6, qup2_se1, _, _, _, _, _, _, _, _, _, egpio),
+	[7] = PINGROUP(7, qup2_se1, _, _, _, _, _, _, _, _, _, egpio),
+	[8] = PINGROUP(8, qup3_se1, ibi_i3c, _, _, _, _, _, _, _, _, _),
+	[9] = PINGROUP(9, qup3_se1, ibi_i3c, _, _, _, _, _, _, _, _, _),
+	[10] = PINGROUP(10, qup3_se1, _, tsense_clm, tsense_pwm, _, _, _, _, _, _, _),
+	[11] = PINGROUP(11, qup3_se1, _, _, _, _, _, _, _, _, _, _),
+	[12] = PINGROUP(12, qup3_se2, ibi_i3c, qup3_se1, _, _, _, _, _, _, _, _),
+	[13] = PINGROUP(13, qup3_se2, ibi_i3c, qup3_se1, _, _, _, _, _, _, _, _),
+	[14] = PINGROUP(14, qup3_se2, _, _, _, _, _, _, _, _, _, _),
+	[15] = PINGROUP(15, qup3_se2, cci_async_in, qup3_se1, _, _, _, _, _, _, _, _),
+	[16] = PINGROUP(16, qup3_se3, _, _, _, _, _, _, _, _, _, _),
+	[17] = PINGROUP(17, qup3_se3, _, _, _, _, _, _, _, _, _, _),
+	[18] = PINGROUP(18, wcn_sw_ctrl, qup3_se3, _, _, _, _, _, _, _, _, _),
+	[19] = PINGROUP(19, wcn_sw_ctrl, qup3_se3, _, _, _, _, _, _, _, _, _),
+	[20] = PINGROUP(20, qup3_se4, _, _, _, _, _, _, _, _, _, _),
+	[21] = PINGROUP(21, qup3_se4, _, _, _, _, _, _, _, _, _, _),
+	[22] = PINGROUP(22, qup3_se4, _, _, _, _, _, _, _, _, _, _),
+	[23] = PINGROUP(23, qup3_se4, _, _, _, _, _, _, _, _, _, _),
+	[24] = PINGROUP(24, qup3_se5, _, _, _, _, _, _, _, _, _, _),
+	[25] = PINGROUP(25, qup3_se5, _, _, _, _, _, _, _, _, _, _),
+	[26] = PINGROUP(26, qup3_se5, _, _, _, _, _, _, _, _, _, _),
+	[27] = PINGROUP(27, qup3_se5, qdss_cti, _, _, _, _, _, _, _, _, _),
+	[28] = PINGROUP(28, qup4_se1, ibi_i3c, _, _, _, _, _, _, _, _, egpio),
+	[29] = PINGROUP(29, qup4_se1, ibi_i3c, _, _, _, _, _, _, _, _, egpio),
+	[30] = PINGROUP(30, qup4_se1, _, _, _, _, _, _, _, _, _, egpio),
+	[31] = PINGROUP(31, qup4_se1, qdss_cti, _, _, _, _, _, _, _, _, egpio),
+	[32] = PINGROUP(32, qup4_se2, ibi_i3c, _, _, _, _, _, _, _, _, _),
+	[33] = PINGROUP(33, qup4_se2, ibi_i3c, _, _, _, _, _, _, _, _, _),
+	[34] = PINGROUP(34, qup4_se2, _, _, _, _, _, _, _, _, _, _),
+	[35] = PINGROUP(35, qup4_se2, _, _, _, _, _, _, _, _, _, _),
+	[36] = PINGROUP(36, qup1_se4, uim1, ibi_i3c, _, _, _, _, _, _, _, _),
+	[37] = PINGROUP(37, qup1_se4, uim1, ibi_i3c, _, _, _, _, _, _, _, _),
+	[38] = PINGROUP(38, qup1_se4, _, _, _, _, _, _, _, _, _, _),
+	[39] = PINGROUP(39, qup1_se4, uim1, _, _, _, _, _, _, _, _, _),
+	[40] = PINGROUP(40, qup1_se2, ddr_bist, _, gnss_adc, _, _, _, _, _, _, _),
+	[41] = PINGROUP(41, qup1_se2, ddr_bist, _, gnss_adc, _, _, _, _, _, _, _),
+	[42] = PINGROUP(42, qup1_se2, gnss_adc, _, _, _, _, _, _, _, _, _),
+	[43] = PINGROUP(43, qup1_se2, _, ddr_pxi, _, _, _, _, _, _, _, _),
+	[44] = PINGROUP(44, qup1_se3, ddr_bist, ddr_pxi, _, _, _, _, _, _, _, _),
+	[45] = PINGROUP(45, qup1_se3, ddr_bist, ddr_pxi, _, _, _, _, _, _, _, _),
+	[46] = PINGROUP(46, qup1_se3, ddr_pxi, _, _, _, _, _, _, _, _, _),
+	[47] = PINGROUP(47, qup1_se3, dp_hot, _, _, _, _, _, _, _, _, _),
+	[48] = PINGROUP(48, qup4_se0, ibi_i3c, _, _, _, _, _, _, _, _, egpio),
+	[49] = PINGROUP(49, qup4_se0, ibi_i3c, _, _, _, _, _, _, _, _, egpio),
+	[50] = PINGROUP(50, qup4_se0, _, _, _, _, _, _, _, _, _, egpio),
+	[51] = PINGROUP(51, qup4_se0, _, _, _, _, _, _, _, _, _, egpio),
+	[52] = PINGROUP(52, qup1_se5, ddr_pxi, _, _, _, _, _, _, _, _, _),
+	[53] = PINGROUP(53, qup1_se5, _, ddr_pxi, _, _, _, _, _, _, _, _),
+	[54] = PINGROUP(54, qup1_se5, uim1, ddr_pxi, _, _, _, _, _, _, _, _),
+	[55] = PINGROUP(55, qup1_se5, uim1, ddr_pxi, _, _, _, _, _, _, _, _),
+	[56] = PINGROUP(56, qup1_se6, uim1, _, _, _, _, _, _, _, _, _),
+	[57] = PINGROUP(57, qup1_se6, _, _, _, _, _, _, _, _, _, _),
+	[58] = PINGROUP(58, qup1_se6, _, _, _, _, _, _, _, _, _, _),
+	[59] = PINGROUP(59, qup1_se6, usb_phy, vsense_trigger_mirnat, _, _, _, _, _, _, _, _),
+	[60] = PINGROUP(60, qup1_se7, usb_phy, ibi_i3c, _, _, _, _, _, _, _, _),
+	[61] = PINGROUP(61, qup1_se7, ibi_i3c, _, _, _, _, _, _, _, _, _),
+	[62] = PINGROUP(62, qup1_se7, _, _, _, _, _, _, _, _, _, _),
+	[63] = PINGROUP(63, qup1_se7, _, _, _, _, _, _, _, _, _, _),
+	[64] = PINGROUP(64, qup3_se0_01, qup3_se0_23, rng_rosc, tmess_rng, _, _, _, _, _, _, _),
+	[65] = PINGROUP(65, qup3_se0_01, qup3_se0_23, rng_rosc, tmess_rng, _, _, _, _, _, _, _),
+	[66] = PINGROUP(66, i2chub0_se0, rng_rosc, tmess_rng, _, _, _, _, _, _, _, _),
+	[67] = PINGROUP(67, i2chub0_se0, _, _, _, _, _, _, _, _, _, _),
+	[68] = PINGROUP(68, i2chub0_se2, _, _, _, _, _, _, _, _, _, _),
+	[69] = PINGROUP(69, i2chub0_se2, _, _, _, _, _, _, _, _, _, _),
+	[70] = PINGROUP(70, i2chub0_se3, uim1, _, atest_usb, _, _, _, _, _, _, _),
+	[71] = PINGROUP(71, i2chub0_se3, uim1, _, atest_usb, _, _, _, _, _, _, _),
+	[72] = PINGROUP(72, i2chub0_se4, uim1, qdss_cti, _, atest_usb, _, _, _, _, _, _),
+	[73] = PINGROUP(73, i2chub0_se4, qdss_cti, jitter_bist, atest_usb, _, _, _, _, _, _, _),
+	[74] = PINGROUP(74, qup1_se1, aoss_cti, _, _, _, _, _, _, _, _, _),
+	[75] = PINGROUP(75, qup1_se1, aoss_cti, _, _, _, _, _, _, _, _, _),
+	[76] = PINGROUP(76, qup1_se1, aoss_cti, _, _, _, _, _, _, _, _, _),
+	[77] = PINGROUP(77, qup1_se1, aoss_cti, gnss_adc, _, _, _, _, _, _, _, _),
+	[78] = PINGROUP(78, i2chub0_se1, _, _, _, _, _, _, _, _, _, _),
+	[79] = PINGROUP(79, i2chub0_se1, usb0_hs, _, _, _, _, _, _, _, _, _),
+	[80] = PINGROUP(80, qup1_se0, sdc4_data, qspi, _, _, _, _, _, _, _, _),
+	[81] = PINGROUP(81, qup1_se0, sdc4_data, qspi, _, _, _, _, _, _, _, _),
+	[82] = PINGROUP(82, qup1_se0, sdc4_data, qdss_cti, qspi, dbg_out_clk, _, _, _, _, _, _),
+	[83] = PINGROUP(83, qup1_se0, sdc4_clk, qdss_cti, qspi_clk, _, _, _, _, _, _, _),
+	[84] = PINGROUP(84, qup4_se3_01, qup4_se3_23, rng_rosc, tmess_rng, _, _, _, _, _, _, _),
+	[85] = PINGROUP(85, sd_write_protect, _, _, _, _, _, _, _, _, _, _),
+	[86] = PINGROUP(86, mdp_vsync, mdp_vsync0_out, mdp_vsync1_out, mdp_esync1, gcc_gp,
+			_, _, _, _, _, _),
+	[87] = PINGROUP(87, mdp_vsync, mdp_vsync2_out, mdp_vsync3_out, mdp_vsync5_out,
+			mdp_esync2, gcc_gp, _, tsense_clm, tsense_pwm, _, _),
+	[88] = PINGROUP(88, mdp_esync0, mdp_vsync, qup4_se4_l3, tb_trig_sdc, _, _, _, _, _, _, _),
+	[89] = PINGROUP(89, cam_mclk, _, _, _, _, _, _, _, _, _, _),
+	[90] = PINGROUP(90, cam_mclk, _, _, _, _, _, _, _, _, _, _),
+	[91] = PINGROUP(91, cam_mclk, _, _, _, _, _, _, _, _, _, _),
+	[92] = PINGROUP(92, cam_mclk, _, _, _, _, _, _, _, _, _, _),
+	[93] = PINGROUP(93, cam_mclk, _, _, _, _, _, _, _, _, _, _),
+	[94] = PINGROUP(94, cam_mclk, pll_clk_aux, _, _, _, _, _, _, _, _, _),
+	[95] = PINGROUP(95, cam_mclk, _, _, _, _, _, _, _, _, _, _),
+	[96] = PINGROUP(96, cam_mclk, _, _, _, _, _, _, _, _, _, _),
+	[97] = PINGROUP(97, mdp_esync2, qup2_se3, mdp_vsync, tsense_clm, tsense_pwm, _, _,
+			_, _, _, _),
+	[98] = PINGROUP(98, mdp_vsync_e, qup4_se3_l3, mdp_vsync_p, _, _, _, _, _, _, _, _),
+	[99] = PINGROUP(99, sys_throttle, tsense_clm, tsense_pwm, _, _, _, _, _, _, _, _),
+	[100] = PINGROUP(100, mdp_esync1, mdp_esync0, _, _, _, _, _, _, _, _, _),
+	[101] = PINGROUP(101, _, _, _, _, _, _, _, _, _, _, _),
+	[102] = PINGROUP(102, pcie0_rst_n, _, _, _, _, _, _, _, _, _, _),
+	[103] = PINGROUP(103, pcie0_clk_req_n, _, _, _, _, _, _, _, _, _, _),
+	[104] = PINGROUP(104, pll_bist_sync, _, _, _, _, _, _, _, _, _, _),
+	[105] = PINGROUP(105, cci_timer, tsense_clm, _, _, _, _, _, _, _, _, _),
+	[106] = PINGROUP(106, host_rst, cci_timer, tsense_clm, _, _, _, _, _, _, _, _),
+	[107] = PINGROUP(107, cci_i2c3, cci_timer, _, _, _, _, _, _, _, _, _),
+	[108] = PINGROUP(108, cci_i2c4, _, _, _, _, _, _, _, _, _, _),
+	[109] = PINGROUP(109, cci_i2c0, cci_async_in, _, _, _, _, _, _, _, _, _),
+	[110] = PINGROUP(110, cci_i2c0, cci_async_in, _, _, _, _, _, _, _, _, _),
+	[111] = PINGROUP(111, cci_i2c1, _, _, _, _, _, _, _, _, _, _),
+	[112] = PINGROUP(112, cci_i2c1, _, _, _, _, _, _, _, _, _, _),
+	[113] = PINGROUP(113, cci_i2c2, _, _, _, _, _, _, _, _, _, _),
+	[114] = PINGROUP(114, cci_i2c2, _, _, _, _, _, _, _, _, _, _),
+	[115] = PINGROUP(115, cci_i2c5, _, _, _, _, _, _, _, _, _, _),
+	[116] = PINGROUP(116, cci_i2c5, _, _, _, _, _, _, _, _, _, _),
+	[117] = PINGROUP(117, i2s1, qup2_se2, phase_flag, _, _, _, _, _, _, _, _),
+	[118] = PINGROUP(118, i2s1, qup2_se2, phase_flag, _, _, _, _, _, _, _, _),
+	[119] = PINGROUP(119, i2s1, qup2_se2, phase_flag, _, _, _, _, _, _, _, _),
+	[120] = PINGROUP(120, i2s1, qup2_se2, audio_ext_mclk, audio_ref_clk, _, _,
+			_, _, _, _, _),
+	[121] = PINGROUP(121, audio_ext_mclk, qup4_se3_01, qup4_se3_23, _, _, _, _, _, _, _, _),
+	[122] = PINGROUP(122, i2s0, qup2_se3, _, _, _, _, _, _, _, _, _),
+	[123] = PINGROUP(123, i2s0, qup2_se3, _, phase_flag, _, _, _, _, _, _, _),
+	[124] = PINGROUP(124, i2s0, qup2_se3, _, phase_flag, _, _, _, _, _, _, _),
+	[125] = PINGROUP(125, i2s0, qup2_se3, phase_flag, _, _, _, _, _, _, _, _),
+	[126] = PINGROUP(126, uim0, atest_char, _, _, _, _, _, _, _, _, _),
+	[127] = PINGROUP(127, uim0, atest_char, _, _, _, _, _, _, _, _, _),
+	[128] = PINGROUP(128, uim0, atest_char, _, _, _, _, _, _, _, _, _),
+	[129] = PINGROUP(129, uim0, atest_usb, atest_char, _, _, _, _, _, _, _, _),
+	[130] = PINGROUP(130, uim1, qup1_se2, gcc_gp, _, _, _, _, _, _, _, _),
+	[131] = PINGROUP(131, uim1, qup1_se2, gcc_gp, _, _, _, _, _, _, _, _),
+	[132] = PINGROUP(132, uim1, qup1_se2, gcc_gp, _, _, _, _, _, _, _, _),
+	[133] = PINGROUP(133, uim1, atest_char, _, _, _, _, _, _, _, _, _),
+	[134] = PINGROUP(134, _, _, nav_rffe, _, _, _, _, _, _, _, _),
+	[135] = PINGROUP(135, _, _, nav_rffe, _, _, _, _, _, _, _, _),
+	[136] = PINGROUP(136, _, _, _, _, _, _, _, _, _, _, _),
+	[137] = PINGROUP(137, _, _, _, _, _, _, _, _, _, _, _),
+	[138] = PINGROUP(138, _, _, nav_rffe, _, _, _, _, _, _, _, _),
+	[139] = PINGROUP(139, _, _, nav_rffe, _, _, _, _, _, _, _, _),
+	[140] = PINGROUP(140, _, _, _, _, _, _, _, _, _, _, _),
+	[141] = PINGROUP(141, _, _, _, _, _, _, _, _, _, _, _),
+	[142] = PINGROUP(142, _, _, _, _, _, _, _, _, _, _, _),
+	[143] = PINGROUP(143, _, _, _, _, _, _, _, _, _, _, _),
+	[144] = PINGROUP(144, coex_uart1_rx, coex_espmi, _, _, _, _, _, _, _, _, _),
+	[145] = PINGROUP(145, coex_uart1_tx, coex_espmi, _, _, _, _, _, _, _, _, _),
+	[146] = PINGROUP(146, _, vfr, nav_gpio, tb_trig_sdc, qspi_cs, _, _, _, _, _, _),
+	[147] = PINGROUP(147, _, nav_gpio, sdc4_data, qspi, _, _, _, _, _, _, _),
+	[148] = PINGROUP(148, nav_gpio, _, sdc4_cmd, qspi_cs, _, _, _, _, _, _, _),
+	[149] = PINGROUP(149, cci_i2c4, _, _, _, _, _, _, _, _, _, _),
+	[150] = PINGROUP(150, nav_gpio0, nav_gpio3, _, _, _, _, _, _, _, _, _),
+	[151] = PINGROUP(151, nav_gpio, vfr, modem_pps_in, modem_pps_out, _, _, _, _, _, _, _),
+	[152] = PINGROUP(152, qlink, qdss_cti, _, _, _, _, _, _, _, _, _),
+	[153] = PINGROUP(153, qlink, _, _, _, _, _, _, _, _, _, _),
+	[154] = PINGROUP(154, qlink, _, _, _, _, _, _, _, _, _, _),
+	[155] = PINGROUP(155, wcn_sw_ctrl, _, _, _, _, _, _, _, _, _, _),
+	[156] = PINGROUP(156, wcn_sw_ctrl, _, _, _, _, _, _, _, _, _, _),
+	[157] = PINGROUP(157, _, _, _, _, _, _, _, _, _, _, _),
+	[158] = PINGROUP(158, qdss_cti, gcc_gp, _, _, _, _, _, _, _, _, _),
+	[159] = PINGROUP(159, cci_timer, tsense_clm, _, _, _, _, _, _, _, _, _),
+	[160] = PINGROUP(160, cci_timer, cci_i2c3, _, _, _, _, _, _, _, _, _),
+	[161] = PINGROUP(161, qup4_se4_01, qup4_se4_23, _, _, _, _, _, _, _, _, _),
+	[162] = PINGROUP(162, qup4_se4_01, qup4_se4_23, _, _, _, _, _, _, _, _, _),
+	[163] = PINGROUP(163, _, _, _, _, _, _, _, _, _, _, egpio),
+	[164] = PINGROUP(164, _, _, _, _, _, _, _, _, _, _, egpio),
+	[165] = PINGROUP(165, _, _, _, _, _, _, _, _, _, _, egpio),
+	[166] = PINGROUP(166, _, _, _, _, _, _, _, _, _, _, egpio),
+	[167] = PINGROUP(167, _, _, _, _, _, _, _, _, _, _, egpio),
+	[168] = PINGROUP(168, _, _, _, _, _, _, _, _, _, _, egpio),
+	[169] = PINGROUP(169, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[170] = PINGROUP(170, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[171] = PINGROUP(171, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[172] = PINGROUP(172, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[173] = PINGROUP(173, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[174] = PINGROUP(174, _, _, _, _, _, _, _, _, _, _, egpio),
+	[175] = PINGROUP(175, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[176] = PINGROUP(176, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[177] = PINGROUP(177, _, _, _, _, _, _, _, _, _, _, egpio),
+	[178] = PINGROUP(178, _, _, _, _, _, _, _, _, _, _, egpio),
+	[179] = PINGROUP(179, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[180] = PINGROUP(180, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[181] = PINGROUP(181, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[182] = PINGROUP(182, _, _, _, _, _, _, _, _, _, _, egpio),
+	[183] = PINGROUP(183, _, _, _, _, _, _, _, _, _, _, egpio),
+	[184] = PINGROUP(184, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[185] = PINGROUP(185, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[186] = PINGROUP(186, _, _, _, _, _, _, _, _, _, _, egpio),
+	[187] = PINGROUP(187, _, _, _, _, _, _, _, _, _, _, egpio),
+	[188] = PINGROUP(188, _, _, _, _, _, _, _, _, _, _, egpio),
+	[189] = PINGROUP(189, _, _, _, _, _, _, _, _, _, _, egpio),
+	[190] = PINGROUP(190, _, _, _, _, _, _, _, _, _, _, egpio),
+	[191] = PINGROUP(191, _, _, _, _, _, _, _, _, _, _, egpio),
+	[192] = PINGROUP(192, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[193] = PINGROUP(193, _, _, _, _, _, _, _, _, _, _, egpio),
+	[194] = PINGROUP(194, _, _, _, _, _, _, _, _, _, _, egpio),
+	[195] = PINGROUP(195, _, _, _, _, _, _, _, _, _, _, egpio),
+	[196] = PINGROUP(196, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[197] = PINGROUP(197, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[198] = PINGROUP(198, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[199] = PINGROUP(199, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[200] = PINGROUP(200, _, _, _, _, _, _, _, _, _, _, egpio),
+	[201] = PINGROUP(201, _, _, _, _, _, _, _, _, _, _, egpio),
+	[202] = PINGROUP(202, _, _, _, _, _, _, _, _, _, _, egpio),
+	[203] = PINGROUP(203, _, _, _, _, _, _, _, _, _, _, egpio),
+	[204] = PINGROUP(204, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[205] = PINGROUP(205, _, _, _, _, _, _, _, _, _, _, egpio),
+	[206] = PINGROUP(206, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[207] = PINGROUP(207, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[208] = PINGROUP(208, qup2_se4_01, qup2_se4_23, phase_flag, _, _, _, _, _, _, _, egpio),
+	[209] = PINGROUP(209, qup2_se4_01, qup2_se4_23, _, _, _, _, _, _, _, _, egpio),
+	[210] = PINGROUP(210, phase_flag, _, _, _, _, _, _, _, _, _, _),
+	[211] = PINGROUP(211, phase_flag, _, _, _, _, _, _, _, _, _, _),
+	[212] = PINGROUP(212, _, _, _, _, _, _, _, _, _, _, egpio),
+	[213] = PINGROUP(213, _, _, _, _, _, _, _, _, _, _, egpio),
+	[214] = PINGROUP(214, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[215] = PINGROUP(215, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[216] = PINGROUP(216, phase_flag, _, _, _, _, _, _, _, _, _, egpio),
+	[217] = PINGROUP(217, _, _, _, _, _, _, _, _, _, _, egpio),
+	[218] = PINGROUP(218, _, _, _, _, _, _, _, _, _, _, egpio),
+	[219] = PINGROUP(219, _, _, _, _, _, _, _, _, _, _, _),
+	[220] = PINGROUP(220, _, _, _, _, _, _, _, _, _, _, _),
+	[221] = PINGROUP(221, pcie1_clk_req_n, _, _, _, _, _, _, _, _, _, _),
+	[222] = PINGROUP(222, _, _, _, _, _, _, _, _, _, _, _),
+	[223] = PINGROUP(223, tsense_pwm, _, _, _, _, _, _, _, _, _, _),
+	[224] = PINGROUP(224, tsense_pwm, _, _, _, _, _, _, _, _, _, _),
+	[225] = PINGROUP(225, tsense_pwm, _, _, _, _, _, _, _, _, _, _),
+	[226] = UFS_RESET(ufs_reset, 0xf1004, 0xf2000),
+	[227] = SDC_QDSD_PINGROUP(sdc2_clk, 0xe6000, 14, 6),
+	[228] = SDC_QDSD_PINGROUP(sdc2_cmd, 0xe6000, 11, 3),
+	[229] = SDC_QDSD_PINGROUP(sdc2_data, 0xe6000, 9, 0),
+};
+
+static const struct msm_gpio_wakeirq_map hawi_pdc_map[] = {
+	{ 0, 105 },   { 3, 113 },   { 4, 106 },   { 7, 107 },   { 8, 108 },   { 11, 109 },
+	{ 12, 115 },  { 15, 131 },  { 16, 116 },  { 17, 141 },  { 18, 143 },  { 19, 112 },
+	{ 23, 117 },  { 24, 118 },  { 27, 119 },  { 28, 125 },  { 31, 126 },  { 32, 127 },
+	{ 35, 101 },  { 36, 128 },  { 39, 129 },  { 43, 130 },  { 47, 154 },  { 48, 135 },
+	{ 51, 114 },  { 55, 104 },  { 57, 136 },  { 58, 137 },  { 59, 138 },  { 60, 139 },
+	{ 61, 145 },  { 63, 124 },  { 64, 110 },  { 65, 123 },  { 67, 132 },  { 68, 146 },
+	{ 69, 147 },  { 75, 151 },  { 77, 148 },  { 78, 149 },  { 79, 155 },  { 80, 156 },
+	{ 81, 157 },  { 82, 158 },  { 84, 134 },  { 85, 159 },  { 86, 160 },  { 87, 161 },
+	{ 88, 162 },  { 95, 163 },  { 96, 164 },  { 97, 133 },  { 98, 150 },  { 99, 111 },
+	{ 101, 165 }, { 102, 166 }, { 103, 167 }, { 104, 168 }, { 120, 169 }, { 123, 170 },
+	{ 125, 171 }, { 129, 153 }, { 133, 100 }, { 144, 172 }, { 146, 173 }, { 151, 174 },
+	{ 152, 175 }, { 155, 122 }, { 158, 120 }, { 162, 142 }, { 164, 176 }, { 165, 177 },
+	{ 167, 178 }, { 168, 179 }, { 174, 180 }, { 177, 181 }, { 179, 182 }, { 183, 183 },
+	{ 184, 184 }, { 185, 185 }, { 186, 152 }, { 188, 144 }, { 202, 102 }, { 203, 103 },
+	{ 205, 140 }, { 209, 186 }, { 213, 121 }, { 216, 187 }, { 221, 188 }, { 222, 189 },
+	{ 223, 190 }, { 224, 191 }, { 225, 192 },
+};
+
+static const struct msm_pinctrl_soc_data hawi_tlmm = {
+	.pins = hawi_pins,
+	.npins = ARRAY_SIZE(hawi_pins),
+	.functions = hawi_functions,
+	.nfunctions = ARRAY_SIZE(hawi_functions),
+	.groups = hawi_groups,
+	.ngroups = ARRAY_SIZE(hawi_groups),
+	.ngpios = 227,
+	.wakeirq_map = hawi_pdc_map,
+	.nwakeirq_map = ARRAY_SIZE(hawi_pdc_map),
+	.egpio_func = 11,
+};
+
+static int hawi_tlmm_probe(struct platform_device *pdev)
+{
+	return msm_pinctrl_probe(pdev, &hawi_tlmm);
+}
+
+static const struct of_device_id hawi_tlmm_of_match[] = {
+	{ .compatible = "qcom,hawi-tlmm", },
+	{},
+};
+
+static struct platform_driver hawi_tlmm_driver = {
+	.driver = {
+		.name = "hawi-tlmm",
+		.of_match_table = hawi_tlmm_of_match,
+	},
+	.probe = hawi_tlmm_probe,
+};
+
+static int __init hawi_tlmm_init(void)
+{
+	return platform_driver_register(&hawi_tlmm_driver);
+}
+arch_initcall(hawi_tlmm_init);
+
+static void __exit hawi_tlmm_exit(void)
+{
+	platform_driver_unregister(&hawi_tlmm_driver);
+}
+module_exit(hawi_tlmm_exit);
+
+MODULE_DESCRIPTION("QTI Hawi TLMM driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(of, hawi_tlmm_of_match);

-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 1/2] dt-bindings: pinctrl: qcom: Describe Hawi TLMM block
From: Mukesh Ojha @ 2026-04-08 14:15 UTC (permalink / raw)
  To: Bjorn Andersson, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Mukesh Ojha
  Cc: linux-arm-msm, linux-gpio, devicetree, linux-kernel
In-Reply-To: <20260408-hawi-pinctrl-v2-0-fd7f681f5e05@oss.qualcomm.com>

The Top Level Mode Multiplexer (TLMM) in the Qualcomm Hawi SoC
provides GPIO and pinctrl functionality for UFS, SDC and 226
GPIO pins.

Add a DeviceTree binding to describe the TLMM block on Qualcomm's
Hawi SoC.

Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 .../bindings/pinctrl/qcom,hawi-tlmm.yaml           | 120 +++++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,hawi-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,hawi-tlmm.yaml
new file mode 100644
index 000000000000..3b3961789860
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,hawi-tlmm.yaml
@@ -0,0 +1,120 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/qcom,hawi-tlmm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. Hawi TLMM block
+
+maintainers:
+  - Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
+
+description:
+  Top Level Mode Multiplexer pin controller in Qualcomm Hawi SoC.
+
+allOf:
+  - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
+
+properties:
+  compatible:
+    const: qcom,hawi-tlmm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  gpio-reserved-ranges:
+    minItems: 1
+    maxItems: 113
+
+  gpio-line-names:
+    maxItems: 226
+
+patternProperties:
+  "-state$":
+    oneOf:
+      - $ref: "#/$defs/qcom-hawi-tlmm-state"
+      - patternProperties:
+          "-pins$":
+            $ref: "#/$defs/qcom-hawi-tlmm-state"
+        additionalProperties: false
+
+$defs:
+  qcom-hawi-tlmm-state:
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+    $ref: qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state
+    unevaluatedProperties: false
+
+    properties:
+      pins:
+        description:
+          List of gpio pins affected by the properties specified in this
+          subnode.
+        items:
+          oneOf:
+            - pattern: "^gpio([0-9]|[1-9][0-9]|1[0-9][0-9]|20[0-9]|21[0-9]|22[0-5])$"
+            - enum: [ ufs_reset, sdc2_clk, sdc2_cmd, sdc2_data ]
+        minItems: 1
+        maxItems: 36
+
+      function:
+        description:
+          Specify the alternative function to be configured for the specified
+          pins.
+        enum: [ gpio, aoss_cti, atest_char, atest_usb, audio_ext_mclk,
+                audio_ref_clk, cam_mclk, cci_async_in, cci_i2c0, cci_i2c1,
+                cci_i2c2, cci_i2c3, cci_i2c4, cci_i2c5, cci_timer, coex_espmi,
+                coex_uart1_rx, coex_uart1_tx, dbg_out_clk, ddr_bist, ddr_pxi,
+                dp_hot, egpio, gcc_gp, gnss_adc, host_rst, i2chub0_se0,
+                i2chub0_se1, i2chub0_se2, i2chub0_se3, i2chub0_se4, i2s0, i2s1,
+                ibi_i3c, jitter_bist, mdp_esync0, mdp_esync1, mdp_esync2,
+                mdp_vsync, mdp_vsync_e, mdp_vsync_p, mdp_vsync0_out,
+                mdp_vsync1_out, mdp_vsync2_out, mdp_vsync3_out, mdp_vsync5_out,
+                modem_pps_in, modem_pps_out, nav_gpio, nav_gpio0, nav_gpio3,
+                nav_rffe, pcie0_clk_req_n, pcie0_rst_n, pcie1_clk_req_n,
+                phase_flag, pll_bist_sync, pll_clk_aux, qdss_cti, qlink,
+                qspi, qspi_clk, qspi_cs, qup1_se0, qup1_se1, qup1_se2,
+                qup1_se3, qup1_se4, qup1_se5, qup1_se6, qup1_se7, qup2_se0,
+                qup2_se1, qup2_se2, qup2_se3, qup2_se4_01, qup2_se4_23,
+                qup3_se0_01, qup3_se0_23, qup3_se1, qup3_se2, qup3_se3,
+                qup3_se4, qup3_se5, qup4_se0, qup4_se1, qup4_se2, qup4_se3_01,
+                qup4_se3_23, qup4_se3_l3, qup4_se4_01, qup4_se4_23, qup4_se4_l3,
+                rng_rosc, sd_write_protect, sdc4_clk, sdc4_cmd, sdc4_data,
+                sys_throttle, tb_trig_sdc, tmess_rng, tsense_clm, tsense_pwm,
+                uim0, uim1, usb0_hs, usb_phy, vfr, vsense_trigger_mirnat,
+                wcn_sw_ctrl ]
+
+    required:
+      - pins
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    tlmm: pinctrl@f100000 {
+        compatible = "qcom,hawi-tlmm";
+        reg = <0x0f100000 0x300000>;
+        interrupts = <GIC_ESPI 272 IRQ_TYPE_LEVEL_HIGH>;
+        gpio-controller;
+        #gpio-cells = <2>;
+        gpio-ranges = <&tlmm 0 0 227>;
+        interrupt-controller;
+        #interrupt-cells = <2>;
+
+        qup-uart7-state {
+          pins = "gpio62", "gpio63";
+          function = "qup1_se7";
+        };
+    };
+...

-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 0/2] pinctrl: qcom: Introduce Pinctrl for Hawi SoC
From: Mukesh Ojha @ 2026-04-08 14:15 UTC (permalink / raw)
  To: Bjorn Andersson, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Mukesh Ojha
  Cc: linux-arm-msm, linux-gpio, devicetree, linux-kernel,
	Konrad Dybcio

Introduce Top Level Mode Multiplexer dt-binding and driver for upcoming
Qualcomm Hawi SoC.

Changes in v2: https://lore.kernel.org/lkml/20260401-hawi-pinctrl-v1-0-4718da24e531@oss.qualcomm.com/#t
  - Addressed some of comment raised by Bjorn on following
   	o Grouping i2s0_* to just i2s0 and same goes for i2s1_* to i2s1.
	o Group the function such as qup3_se0_l0 and qup3_se0_l1 and qup3_se0_l2
          and qup3_se0_l3 together with qup3_se0_01 and qup3_se0_23 and
	  do the same of the other similar instances.
        o uim0_* to uim and uim1_* to uim1 as they are non-overlapping.
	o Grouping change for nav_gpios and qlink.
	o cci_i2c_sda and cci_i2c_scl to its respective serial engine
	  numbering replacing with cci_i2c0, cci_i2c1 ... etc.,

---
Mukesh Ojha (2):
      dt-bindings: pinctrl: qcom: Describe Hawi TLMM block
      pinctrl: qcom: Add Hawi pinctrl driver

 .../bindings/pinctrl/qcom,hawi-tlmm.yaml           |  120 ++
 drivers/pinctrl/qcom/Kconfig.msm                   |   10 +
 drivers/pinctrl/qcom/Makefile                      |    1 +
 drivers/pinctrl/qcom/pinctrl-hawi.c                | 1610 ++++++++++++++++++++
 4 files changed, 1741 insertions(+)
---
base-commit: f3e6330d7fe42b204af05a2dbc68b379e0ad179e
change-id: 20260408-hawi-pinctrl-a58d36ec2fc2

Best regards,
-- 
-Mukesh Ojha


^ permalink raw reply

* Re: [PATCH v6 13/21] drm: renesas: rz-du: mipi_dsi: Add RZ_MIPI_DSI_FEATURE_GPO0R feature
From: Tommaso Merciai @ 2026-04-08 14:12 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: tomm.merciai, geert, linux-renesas-soc, biju.das.jz,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Magnus Damm,
	Tomi Valkeinen, dri-devel, devicetree, linux-kernel, linux-clk
In-Reply-To: <20260408123102.GA1960713@killaraus.ideasonboard.com>

Hi Laurent,
Thanks for your review.

On 4/8/26 14:31, Laurent Pinchart wrote:
> On Wed, Apr 08, 2026 at 12:36:58PM +0200, Tommaso Merciai wrote:
>> The MIPI DSI ip found in the RZ/G3E SoC select the video input clock
>> based on the DU instance actually connected using the GPO0R register.
>>
>> Add this feature to the driver using `RZ_MIPI_DSI_FEATURE_GPO0R`, update
>> the code accordingly to manage the vclk selection with the introduction
>> of `rzg2l_mipi_dsi_get_input_port()`.
>>
>> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
>> ---
>> v5->v6:
>>   - Moved rzg2l_mipi_dsi_link_write() into rzv2h_mipi_dsi_dphy_init()
>>     + comments from HW Manual.
>>
>> v4->v5:
>>   - No changes.
>>
>> v3->v4:
>>   - No changes.
>>
>> v2->v3:
>>   - No changes.
>>
>> v1->v2:
>>   - No changes.
>>
>>   .../gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c    | 71 +++++++++++++++++--
>>   .../drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h   |  3 +
>>   2 files changed, 68 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
>> index be6dbf19a24e..947c8e15fc4b 100644
>> --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
>> +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
>> @@ -37,7 +37,9 @@ MODULE_IMPORT_NS("RZV2H_CPG");
>>   
>>   #define RZG2L_DCS_BUF_SIZE	128 /* Maximum DCS buffer size in external memory. */
>>   
>> +#define RZ_MIPI_DSI_MAX_INPUT	2
>>   #define RZ_MIPI_DSI_FEATURE_16BPP	BIT(0)
>> +#define RZ_MIPI_DSI_FEATURE_GPO0R	BIT(1)
>>   
>>   struct rzg2l_mipi_dsi;
>>   
>> @@ -81,13 +83,14 @@ struct rzg2l_mipi_dsi {
>>   	struct drm_bridge bridge;
>>   	struct drm_bridge *next_bridge;
>>   
>> -	struct clk *vclk;
>> +	struct clk *vclk[RZ_MIPI_DSI_MAX_INPUT];
>>   	struct clk *lpclk;
>>   
>>   	enum mipi_dsi_pixel_format format;
>>   	unsigned int num_data_lanes;
>>   	unsigned int lanes;
>>   	unsigned long mode_flags;
>> +	u8 vclk_idx;
>>   
>>   	struct rzv2h_dsi_mode_calc mode_calc;
>>   
>> @@ -543,8 +546,8 @@ static int rzg2l_dphy_conf_clks(struct rzg2l_mipi_dsi *dsi, unsigned long mode_f
>>   	unsigned long vclk_rate;
>>   	unsigned int bpp;
>>   
>> -	clk_set_rate(dsi->vclk, mode_freq * KILO);
>> -	vclk_rate = clk_get_rate(dsi->vclk);
>> +	clk_set_rate(dsi->vclk[dsi->vclk_idx], mode_freq * KILO);
>> +	vclk_rate = clk_get_rate(dsi->vclk[dsi->vclk_idx]);
>>   	if (vclk_rate != mode_freq * KILO)
>>   		dev_dbg(dsi->dev, "Requested vclk rate %lu, actual %lu mismatch\n",
>>   			mode_freq * KILO, vclk_rate);
>> @@ -687,6 +690,19 @@ static int rzv2h_mipi_dsi_dphy_init(struct rzg2l_mipi_dsi *dsi,
>>   	rzg2l_mipi_dsi_phy_write(dsi, PLLCLKSET1R,
>>   				 FIELD_PREP(PLLCLKSET1R_PLL_K, dsi_parameters->k));
>>   
>> +	/*
>> +	 * From RZ/G3E HW manual (Rev.1.15) section 9.5.3 Operation,
>> +	 * 9.5.3.1 Power on Reset and Initial Settings for All Operations.
>> +	 * Figure 9.5-4 Power On/Off Sequence show that after writing to
>> +	 * GPO0R.VICH register we need to wait for more than 1 x tp before
>> +	 * writing to PLLENR.PLLEN.
>> +	 *
>> +	 * Note: GPO0R is a link register, not a PHY register. This setting
>> +	 * is specific to RZ/G3E.
>> +	 */
>> +	if (dsi->info->features & RZ_MIPI_DSI_FEATURE_GPO0R)
>> +		rzg2l_mipi_dsi_link_write(dsi, GPO0R, dsi->vclk_idx);
>> +
>>   	/*
>>   	 * From RZ/V2H HW manual (Rev.1.20) section 9.5.3 Operation,
>>   	 * (C) After write to D-PHY registers we need to wait for more than 1 x tp
>> @@ -1005,6 +1021,37 @@ static int rzg2l_mipi_dsi_stop_video(struct rzg2l_mipi_dsi *dsi)
>>   	return ret;
>>   }
>>   
>> +static int rzg2l_mipi_dsi_get_input_port(struct rzg2l_mipi_dsi *dsi)
>> +{
>> +	struct device_node *np = dsi->dev->of_node;
>> +	struct device_node *remote_ep, *ep_node;
>> +	struct of_endpoint ep;
>> +	bool ep_enabled;
>> +	int in_port;
>> +
>> +	/* DSI can have only one port enabled */
> 
> Why is that ? The hardware supports dynamic input selection, why can't
> it be supported at runtime ?

For runtime/dynamic you mean using DT overlay??
like, remove:

Removing - DU0 --> DSI (input 0 | port@0 ) overlay and
install  - DU1 --> DSI (input 1 | port@1 ) overlay and
viceversa?

Kind Regards,
Tommaso

> 
>> +	for_each_endpoint_of_node(np, ep_node) {
>> +		of_graph_parse_endpoint(ep_node, &ep);
>> +		if (ep.port >= RZ_MIPI_DSI_MAX_INPUT)
>> +			break;
>> +
>> +		remote_ep = of_graph_get_remote_endpoint(ep_node);
>> +		ep_enabled = of_device_is_available(remote_ep);
>> +		of_node_put(remote_ep);
>> +
>> +		if (ep_enabled) {
>> +			in_port = ep.port;
>> +			break;
>> +		}
>> +	}
>> +
>> +	if (!ep_enabled)
>> +		return -EINVAL;
>> +
>> +	dev_dbg(dsi->dev, "input port@%d\n", in_port);
>> +	return in_port;
>> +}
>> +
>>   /* -----------------------------------------------------------------------------
>>    * Bridge
>>    */
>> @@ -1425,9 +1472,21 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev)
>>   	if (IS_ERR(dsi->mmio))
>>   		return PTR_ERR(dsi->mmio);
>>   
>> -	dsi->vclk = devm_clk_get(dsi->dev, "vclk");
>> -	if (IS_ERR(dsi->vclk))
>> -		return PTR_ERR(dsi->vclk);
>> +	dsi->vclk[0] = devm_clk_get(dsi->dev, "vclk");
>> +		if (IS_ERR(dsi->vclk[0]))
>> +			return PTR_ERR(dsi->vclk[0]);
>> +
>> +	if (dsi->info->features & RZ_MIPI_DSI_FEATURE_GPO0R) {
>> +		dsi->vclk[1] = devm_clk_get(dsi->dev, "vclk2");
>> +		if (IS_ERR(dsi->vclk[1]))
>> +			return PTR_ERR(dsi->vclk[1]);
>> +
>> +		ret = rzg2l_mipi_dsi_get_input_port(dsi);
>> +		if (ret < 0)
>> +			return dev_err_probe(dsi->dev, -EINVAL,
>> +					     "No available input port\n");
>> +		dsi->vclk_idx = ret;
>> +	}
>>   
>>   	dsi->lpclk = devm_clk_get(dsi->dev, "lpclk");
>>   	if (IS_ERR(dsi->lpclk))
>> diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
>> index 2bef20566648..cee2e0bc5dc5 100644
>> --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
>> +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
>> @@ -83,6 +83,9 @@
>>   #define LINKSR_SQCHRUN1			BIT(4)
>>   #define LINKSR_SQCHRUN0			BIT(0)
>>   
>> +/* RZ/G3E General Purpose Output 0 Register */
>> +#define GPO0R				0xc0
>> +
>>   /* Tx Set Register */
>>   #define TXSETR				0x100
>>   #define TXSETR_NUMLANECAP		(0x3 << 16)
> 


^ permalink raw reply

* Re: [PATCH V11 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
From: Manivannan Sadhasivam @ 2026-04-08 14:10 UTC (permalink / raw)
  To: Sherry Sun
  Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	Frank Li, s.hauer@pengutronix.de, kernel@pengutronix.de,
	festevam@gmail.com, lpieralisi@kernel.org, kwilczynski@kernel.org,
	bhelgaas@google.com, Hongxing Zhu, l.stach@pengutronix.de,
	imx@lists.linux.dev, linux-pci@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <VI0PR04MB12114A60C4A7E43ED62A32B04925BA@VI0PR04MB12114.eurprd04.prod.outlook.com>

On Wed, Apr 08, 2026 at 06:34:02AM +0000, Sherry Sun wrote:

[...]

> > > +/**
> > > + * pci_host_common_parse_port - Parse a single Root Port node
> > > + * @dev: Device pointer
> > > + * @bridge: PCI host bridge
> > > + * @node: Device tree node of the Root Port
> > > + *
> > > + * Returns: 0 on success, negative error code on failure  */ static
> > > +int pci_host_common_parse_port(struct device *dev,
> > > +				      struct pci_host_bridge *bridge,
> > > +				      struct device_node *node)
> > > +{
> > > +	struct pci_host_port *port;
> > > +	struct gpio_desc *reset;
> > > +
> > > +	reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
> > > +				      "reset", GPIOD_ASIS, "PERST#");
> > 
> > Sorry, I missed this earlier.
> > 
> > Since PERST# is optional, you cannot reliably detect whether the Root Port
> > binding intentionally skipped the PERST# GPIO or legacy binding is used, just
> > by checking for PERST# in Root Port node.
> > 
> > So this helper should do 3 things:
> > 
> > 1. If PERST# is found in Root Port node, use it.
> > 2. If not, check the RC node and if present, return -ENOENT to fallback to the
> > legacy binding.
> > 3. If not found in both nodes, assume that the PERST# is not present in the
> > design, and proceed with parsing Root Port binding further.
> 
> Hi Mani, understand, does the following code looks ok for above three cases?
> 
>     /* Check if PERST# is present in Root Port node */
>     reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
>                       "reset", GPIOD_ASIS, "PERST#");
>     if (IS_ERR(reset)) {
>         /* If error is not -ENOENT, it's a real error */
>         if (PTR_ERR(reset) != -ENOENT)
>             return PTR_ERR(reset);
> 
>         /* PERST# not found in Root Port node, check RC node */
>         rc_has_reset = of_property_read_bool(dev->of_node, "reset-gpios") ||
>                    of_property_read_bool(dev->of_node, "reset-gpio");

Just:
		if (of_property_read_bool(dev->of_node, "reset-gpios") ||
		    of_property_read_bool(dev->of_node, "reset-gpio")) {
			return -ENOENT;
		} 

>         if (rc_has_reset)
>             return -ENOENT;
> 
>         /* No PERST# in either node, assume not present in design */
>         reset = NULL;
>     }
> 
>     port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
>     if (!port)
>         return -ENOMEM;
> ...
> 
> > 
> > But there is one more important limitation here. Right now, this API only
> > handles PERST#. But if another vendor tries to use it and if they need other
> > properties such as PHY, clocks etc... those resources should be fetched
> > optionally only by this helper. But if the controller has a hard dependency on
> > those resources, the driver will fail to operate.
> > 
> > I don't think we can fix this limitation though and those platforms should
> > ensure that the resource dependency is correctly modeled in DT binding and
> > the DTS is validated properly. It'd be good to mention this in the kernel doc of
> > this API.
> 
> Ok, I will add a NOTE for this in this API description.
> 
> > 
> > > +	if (IS_ERR(reset))
> > > +		return PTR_ERR(reset);
> > > +
> > > +	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> > > +	if (!port)
> > > +		return -ENOMEM;
> > > +
> > > +	port->reset = reset;
> > > +	INIT_LIST_HEAD(&port->list);
> > > +	list_add_tail(&port->list, &bridge->ports);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +/**
> > > + * pci_host_common_parse_ports - Parse Root Port nodes from device
> > > +tree
> > > + * @dev: Device pointer
> > > + * @bridge: PCI host bridge
> > > + *
> > > + * This function iterates through child nodes of the host bridge and
> > > +parses
> > > + * Root Port properties (currently only reset GPIO).
> > > + *
> > > + * Returns: 0 on success, -ENOENT if no ports found, other negative
> > > +error codes
> > > + * on failure
> > > + */
> > > +int pci_host_common_parse_ports(struct device *dev, struct
> > > +pci_host_bridge *bridge) {
> > > +	int ret = -ENOENT;
> > > +
> > > +	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> > > +		if (!of_node_is_type(of_port, "pci"))
> > > +			continue;
> > > +		ret = pci_host_common_parse_port(dev, bridge, of_port);
> > > +		if (ret)
> > > +			return ret;
> > 
> > As Sashiko flagged, you need to make sure that devm_add_action_or_reset()
> > is added even during the error path:
> 
> Yes, it needs to be fixed. We can handle it with the following two methods, I am not sure which method is better or more preferable?
> 
> #1: register cleanup action after first successful port parse and use cleanup_registered flag to avoid duplicate register.
>     int ret = -ENOENT;    
>     bool cleanup_registered = false;
> 
>     for_each_available_child_of_node_scoped(dev->of_node, of_port) {
>         if (!of_node_is_type(of_port, "pci"))
>             continue;
>         ret = pci_host_common_parse_port(dev, bridge, of_port);
>         if (ret)
>             return ret;
> 
>         /* Register cleanup action after first successful port parse */
>         if (!cleanup_registered) {
>             ret = devm_add_action_or_reset(dev,
>                                pci_host_common_delete_ports,
>                                &bridge->ports);

Even if you register devm_add_action_or_reset(), it won't be called when
pci_host_common_parse_port() fails since the legacy fallback will be used.

So you need to manually call pci_host_common_delete_ports() in the error path.

- Mani

-- 
மணிவண்ணன் சதாசிவம்

^ permalink raw reply

* Re: [PATCH v2 0/3] Exynos850 APM-to-AP mailbox support
From: Alexey Klimov @ 2026-04-08 14:05 UTC (permalink / raw)
  To: Tudor Ambarus, Krzysztof Kozlowski, Sylwester Nawrocki,
	Chanwoo Choi, Alim Akhtar, Sam Protsenko, Michael Turquette,
	Stephen Boyd, Rob Herring, Conor Dooley, Jassi Brar
  Cc: Krzysztof Kozlowski, Peter Griffin, linux-samsung-soc,
	linux-arm-kernel, linux-clk, devicetree, linux-kernel
In-Reply-To: <d9c714fa-988c-4b0d-b756-c6e7a40da587@linaro.org>

On Thu Apr 2, 2026 at 9:45 AM BST, Tudor Ambarus wrote:
> Hi!
>
> On 4/2/26 5:20 AM, Alexey Klimov wrote:
>> This patch series introduces support for the APM-to-AP mailbox on the
>
> If AP initiates the communication and APM responds, shouldn't this be called
> AP-to-APM mailbox?

Yes, there is some inconsistency in the naming, in the downstream too.
If this has to be aligned with datasheet like in the comments to another
patch in this series, then name should be APM-to-AP or APM2AP for that
matter.

But let's keep it logical. I will rename it to ap2apm and will re-check.

Thanks,
Alexey



^ permalink raw reply

* Re: [PATCH v6 10/21] dt-bindings: display: renesas,rzg2l-du: Add support for RZ/G3E SoC
From: Tommaso Merciai @ 2026-04-08 14:02 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: tomm.merciai, geert, linux-renesas-soc, biju.das.jz,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Magnus Damm,
	Tomi Valkeinen, dri-devel, devicetree, linux-kernel, linux-clk
In-Reply-To: <20260408122436.GH1928916@killaraus.ideasonboard.com>

Hi Laurent,
Thanks for your review.

On 4/8/26 14:24, Laurent Pinchart wrote:
> On Wed, Apr 08, 2026 at 12:36:55PM +0200, Tommaso Merciai wrote:
>> The RZ/G3E SoC has 2 LCD controllers (LCDC), each containing a Frame
>> Compression Processor (FCPVD), a Video Signal Processor (VSPD), and a
>> Display Unit (DU).
>>
>>   - LCDC0 supports DSI and LVDS (single or dual-channel) outputs.
>>   - LCDC1 supports DSI, LVDS (single-channel), and RGB outputs.
>>
>> Add a new SoC-specific compatible string 'renesas,r9a09g047-du'.
>>
>> Extend patternProperties from "^port@[0-1]$" to "^port@[0-3]$" to
>> allow up to four output ports, and explicitly disable port@2 and port@3
>> for existing SoCs that do not expose them.
>>
>> Describe the four output ports of the RZ/G3E DU:
>>
>>   - port@0: DSI (available on both LCDC instances)
>>   - port@1: DPAD / parallel RGB (LCDC1 only)
>>   - port@2: LVDS channel 0 (LCDC0 only)
>>   - port@3: LVDS channel 1 (available on both LCDC instances)
>>
>> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
>> ---
>> v5->v6:
>>   - Extend patternProperties from "^port@[0-1]$" to "^port@[0-3]$" and
>>     explicitly disable port@2 and port@3 for existing SoCs that do not expose
>>     them.
>>   - Reworked ports numbering + improved/fixed ports descriptions in the
>>     bindings documentation.
>>   - Improved commit body.
>>
>> v4->v5:
>>   - Dropped renesas,id property and updated bindings
>>     accordingly.
>>
>> v2->v3:
>>   - No changes.
>>
>> v2->v3:
>>   - No changes.
>>
>> v1->v2:
>>   - Use single compatible string instead of multiple compatible strings
>>     for the two DU instances, leveraging a 'renesas,id' property to
>>     differentiate between DU0 and DU1.
>>   - Updated commit message accordingly.
>>
>>   .../bindings/display/renesas,rzg2l-du.yaml    | 30 ++++++++++++++++++-
>>   1 file changed, 29 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
>> index 5add3b832eab..32da0b5ec88c 100644
>> --- a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
>> +++ b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
>> @@ -20,6 +20,7 @@ properties:
>>         - enum:
>>             - renesas,r9a07g043u-du # RZ/G2UL
>>             - renesas,r9a07g044-du # RZ/G2{L,LC}
>> +          - renesas,r9a09g047-du # RZ/G3E
>>             - renesas,r9a09g057-du # RZ/V2H(P)
>>         - items:
>>             - enum:
>> @@ -61,7 +62,7 @@ properties:
>>         model-dependent. Each port shall have a single endpoint.
>>   
>>       patternProperties:
>> -      "^port@[0-1]$":
>> +      "^port@[0-3]$":
>>           $ref: /schemas/graph.yaml#/properties/port
>>           unevaluatedProperties: false
>>   
>> @@ -103,6 +104,8 @@ allOf:
>>               port@0:
>>                 description: DPI
>>               port@1: false
>> +            port@2: false
>> +            port@3: false
>>   
>>             required:
>>               - port@0
>> @@ -119,6 +122,8 @@ allOf:
>>                 description: DSI
>>               port@1:
>>                 description: DPI
>> +            port@2: false
>> +            port@3: false
>>   
>>             required:
>>               - port@0
>> @@ -135,9 +140,32 @@ allOf:
>>               port@0:
>>                 description: DSI
>>               port@1: false
>> +            port@2: false
>> +            port@3: false
>>   
>>             required:
>>               - port@0
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: renesas,r9a09g047-du
>> +    then:
>> +      properties:
>> +        ports:
>> +          properties:
>> +            port@0:
>> +              description: DSI
>> +            port@1:
>> +              description: DPAD
>> +            port@2:
>> +              description: LVDS, Channel 0
>> +            port@3:
>> +              description: LVDS, Channel 1
>> +
>> +          required:
>> +            - port@0
>> +            - port@3
> 
> Why are ports 1 and 2 not required ?

About this we had a similar discussion on v5[0]
We are using the same compatible and:

- LCDC0 supports DSI and LVDS (single or dual-channel) outputs.
|
--> then has:
	port@0
	port@2
	port@3
	

  - LCDC1 supports DSI, LVDS (single-channel), and RGB outputs.
|
--> then has:
	port@0
	port@1
	port@3

Then port@1 is required for DU1 but not for DU0.
Same port@2 is required for DU0 but not for DU1.

[0] 
https://patchwork.kernel.org/project/linux-renesas-soc/patch/ca022fdbba5236c36e0cb3095db4c31e8e0cb1b8.1770996493.git.tommaso.merciai.xr@bp.renesas.com/ 


Kind Regards,
Tommaso



> 
>>   
>>   examples:
>>     # RZ/G2L DU
> 


^ permalink raw reply

* Re: [PATCH v3] arm64: dts: imx952: Describe Mali G310 GPU
From: Liviu Dudau @ 2026-04-08 13:56 UTC (permalink / raw)
  To: Guangliu Ding
  Cc: Daniel Almeida, Alice Ryhl, Boris Brezillon, Steven Price,
	David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	dri-devel, devicetree, linux-kernel, imx, linux-arm-kernel
In-Reply-To: <20260407-master-v3-1-5a05cea0c521@nxp.com>

On Tue, Apr 07, 2026 at 11:15:03AM +0800, Guangliu Ding wrote:
> Support Mali G310 GPU on i.MX952 board. Describe this GPU in the DT.
> Include dummy GPU voltage regulator and OPP tables.
> 
> A hardware GPU auto clock‑gating mechanism has been introduced,
> enabling GPUMIX to automatically manage the GPU clock. This improves
> overall response time.
> 
> Signed-off-by: Guangliu Ding <guangliu.ding@nxp.com>

Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>

Best regards,
Liviu

> ---
> This series enable Mali G310 GPU support on i.MX952 boards, the same GPU
> IP as the instance on i.MX95 boards.
> ---
> Changes in v3:
> - Follow the order of interrupts/interrupt-names in arm,mali-valhall-csf.yaml.
> - Drop dt-bindings change in arm,mali-valhall-csf.yaml.
> - Replace "nxp,imx952-mali" with "nxp,imx95-mali" in compatible.
> - Link to v2: https://patch.msgid.link/20260401-master-v2-0-20d3fbcd19d6@nxp.com
> 
> Changes in v2:
> - Improve patch description, adding more GPU information.
> - Remove Reviewed-by tag.
> - Link to v1: https://patch.msgid.link/20260331-master-v1-0-65c8e318d462@nxp.com
> ---
>  arch/arm64/boot/dts/freescale/imx952.dtsi | 36 +++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx952.dtsi b/arch/arm64/boot/dts/freescale/imx952.dtsi
> index 91fe4916ac04..ced09e7a1dc5 100644
> --- a/arch/arm64/boot/dts/freescale/imx952.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx952.dtsi
> @@ -318,6 +318,28 @@ usbphynop2: usbphynop2 {
>  		clock-names = "main_clk";
>  	};
>  
> +	gpu_opp_table: opp-table {
> +		compatible = "operating-points-v2";
> +
> +		opp-500000000 {
> +			opp-hz = /bits/ 64 <500000000>;
> +			opp-hz-real = /bits/ 64 <500000000>;
> +			opp-microvolt = <920000>;
> +		};
> +
> +		opp-800000000 {
> +			opp-hz = /bits/ 64 <800000000>;
> +			opp-hz-real = /bits/ 64 <800000000>;
> +			opp-microvolt = <920000>;
> +		};
> +
> +		opp-1000000000 {
> +			opp-hz = /bits/ 64 <1000000000>;
> +			opp-hz-real = /bits/ 64 <1000000000>;
> +			opp-microvolt = <920000>;
> +		};
> +	};
> +
>  	soc {
>  		compatible = "simple-bus";
>  		#address-cells = <2>;
> @@ -1262,5 +1284,19 @@ usbmisc2: usbmisc@4c200200 {
>  			reg = <0x0 0x4c200200 0x0 0x200>,
>  			      <0x0 0x4c010014 0x0 0x4>;
>  		};
> +
> +		gpu: gpu@4d900000 {
> +			compatible = "nxp,imx95-mali", "arm,mali-valhall-csf";
> +			reg = <0 0x4d900000 0 0x480000>;
> +			interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-names = "job", "mmu", "gpu";
> +			clocks = <&scmi_clk IMX952_CLK_GPU>;
> +			clock-names = "core";
> +			power-domains = <&scmi_devpd IMX952_PD_GPU>;
> +			operating-points-v2 = <&gpu_opp_table>;
> +			dynamic-power-coefficient = <1013>;
> +		};
>  	};
>  };
> 
> ---
> base-commit: 0138af2472dfdef0d56fc4697416eaa0ff2589bd
> change-id: 20260331-master-7ec7ff0fe1b2
> 
> Best regards,
> --  
> Guangliu Ding <guangliu.ding@nxp.com>
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯

^ permalink raw reply


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