Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH net-next v6 03/12] net: airoha: Introduce airoha_gdm_dev struct
From: Lorenzo Bianconi @ 2026-05-12 20:55 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Christian Marangi, Benjamin Larsson, linux-arm-kernel,
	linux-mediatek, netdev, devicetree, Xuegang Lu
In-Reply-To: <20260511-airoha-eth-multi-serdes-v6-3-c899462c4f75@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 31080 bytes --]

On May 11, Lorenzo Bianconi wrote:
> EN7581 and AN7583 SoCs support connecting multiple external SerDes to GDM3
> or GDM4 ports via a hw arbiter that manages the traffic in a TDM manner.
> As a result multiple net_devices can connect to the same GDM{3,4} port
> and there is a theoretical "1:n" relation between GDM port and
> net_devices.
> Introduce airoha_gdm_dev struct to collect net_device related info (e.g.
> net_device and external phy pointer). Please note this is just a
> preliminary patch and we are still supporting a single net_device for
> each GDM port. Subsequent patches will add support for multiple net_devices
> connected to the same GDM port.
> 
> Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  drivers/net/ethernet/airoha/airoha_eth.c | 309 ++++++++++++++++++-------------
>  drivers/net/ethernet/airoha/airoha_eth.h |  13 +-
>  drivers/net/ethernet/airoha/airoha_ppe.c |  17 +-
>  3 files changed, 203 insertions(+), 136 deletions(-)
> 
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> index 3fe2561c85f1..18a89de4d58a 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.c
> +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> @@ -600,6 +600,7 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
>  		struct airoha_qdma_desc *desc = &q->desc[q->tail];
>  		u32 hash, reason, msg1, desc_ctrl;
>  		struct airoha_gdm_port *port;
> +		struct net_device *netdev;
>  		int data_len, len, p;
>  		struct page *page;
>  
> @@ -628,6 +629,7 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
>  			goto free_frag;
>  
>  		port = eth->ports[p];
> +		netdev = port->dev->dev;
>  		if (!q->skb) { /* first buffer */
>  			q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM,
>  						q->buf_size);
> @@ -637,8 +639,8 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
>  			skb_reserve(q->skb, AIROHA_RX_HEADROOM);
>  			__skb_put(q->skb, len);
>  			skb_mark_for_recycle(q->skb);
> -			q->skb->dev = port->dev;
> -			q->skb->protocol = eth_type_trans(q->skb, port->dev);
> +			q->skb->dev = netdev;
> +			q->skb->protocol = eth_type_trans(q->skb, netdev);
>  			q->skb->ip_summed = CHECKSUM_UNNECESSARY;
>  			skb_record_rx_queue(q->skb, qid);
>  		} else { /* scattered frame */
> @@ -656,7 +658,7 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
>  		if (FIELD_GET(QDMA_DESC_MORE_MASK, desc_ctrl))
>  			continue;
>  
> -		if (netdev_uses_dsa(port->dev)) {
> +		if (netdev_uses_dsa(netdev)) {
>  			/* PPE module requires untagged packets to work
>  			 * properly and it provides DSA port index via the
>  			 * DMA descriptor. Report DSA tag to the DSA stack
> @@ -850,6 +852,7 @@ static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)
>  
>  	for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
>  		struct airoha_gdm_port *port = eth->ports[i];
> +		struct airoha_gdm_dev *dev;
>  		int j;
>  
>  		if (!port)
> @@ -858,11 +861,12 @@ static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)
>  		if (port->qdma != qdma)
>  			continue;
>  
> -		for (j = 0; j < port->dev->num_tx_queues; j++) {
> +		dev = port->dev;
> +		for (j = 0; j < dev->dev->num_tx_queues; j++) {
>  			if (airoha_qdma_get_txq(qdma, j) != qid)
>  				continue;
>  
> -			netif_wake_subqueue(port->dev, j);
> +			netif_wake_subqueue(dev->dev, j);
>  		}
>  	}
>  	q->txq_stopped = false;
> @@ -1702,19 +1706,20 @@ static void airoha_update_hw_stats(struct airoha_gdm_port *port)
>  	spin_unlock(&port->stats.lock);
>  }
>  
> -static int airoha_dev_open(struct net_device *dev)
> +static int airoha_dev_open(struct net_device *netdev)
>  {
> -	int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN;
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	struct airoha_qdma *qdma = port->qdma;
>  	u32 pse_port = FE_PSE_PORT_PPE1;
>  
> -	netif_tx_start_all_queues(dev);
> +	netif_tx_start_all_queues(netdev);
>  	err = airoha_set_vip_for_gdm_port(port, true);
>  	if (err)
>  		return err;
>  
> -	if (netdev_uses_dsa(dev))
> +	if (netdev_uses_dsa(netdev))
>  		airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
>  			      GDM_STAG_EN_MASK);
>  	else
> @@ -1742,16 +1747,17 @@ static int airoha_dev_open(struct net_device *dev)
>  	return 0;
>  }
>  
> -static int airoha_dev_stop(struct net_device *dev)
> +static int airoha_dev_stop(struct net_device *netdev)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	struct airoha_qdma *qdma = port->qdma;
>  	int i;
>  
> -	netif_tx_disable(dev);
> +	netif_tx_disable(netdev);
>  	airoha_set_vip_for_gdm_port(port, false);
> -	for (i = 0; i < dev->num_tx_queues; i++)
> -		netdev_tx_reset_subqueue(dev, i);
> +	for (i = 0; i < netdev->num_tx_queues; i++)
> +		netdev_tx_reset_subqueue(netdev, i);
>  
>  	airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
>  				    FE_PSE_PORT_DROP);
> @@ -1772,16 +1778,17 @@ static int airoha_dev_stop(struct net_device *dev)
>  	return 0;
>  }
>  
> -static int airoha_dev_set_macaddr(struct net_device *dev, void *p)
> +static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	int err;
>  
> -	err = eth_mac_addr(dev, p);
> +	err = eth_mac_addr(netdev, p);
>  	if (err)
>  		return err;
>  
> -	airoha_set_macaddr(port, dev->dev_addr);
> +	airoha_set_macaddr(port, netdev->dev_addr);
>  
>  	return 0;
>  }
> @@ -1845,16 +1852,17 @@ static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port)
>  	return 0;
>  }
>  
> -static int airoha_dev_init(struct net_device *dev)
> +static int airoha_dev_init(struct net_device *netdev)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> -	struct airoha_eth *eth = port->eth;
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
> +	struct airoha_eth *eth = dev->eth;
>  	int i;
>  
>  	/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
>  	port->qdma = &eth->qdma[!airoha_is_lan_gdm_port(port)];
> -	port->dev->irq = port->qdma->irq_banks[0].irq;
> -	airoha_set_macaddr(port, dev->dev_addr);
> +	dev->dev->irq = port->qdma->irq_banks[0].irq;
> +	airoha_set_macaddr(port, netdev->dev_addr);
>  
>  	switch (port->id) {
>  	case AIROHA_GDM3_IDX:
> @@ -1879,10 +1887,11 @@ static int airoha_dev_init(struct net_device *dev)
>  	return 0;
>  }
>  
> -static void airoha_dev_get_stats64(struct net_device *dev,
> +static void airoha_dev_get_stats64(struct net_device *netdev,
>  				   struct rtnl_link_stats64 *storage)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	unsigned int start;
>  
>  	airoha_update_hw_stats(port);
> @@ -1901,36 +1910,39 @@ static void airoha_dev_get_stats64(struct net_device *dev,
>  	} while (u64_stats_fetch_retry(&port->stats.syncp, start));
>  }
>  
> -static int airoha_dev_change_mtu(struct net_device *dev, int mtu)
> +static int airoha_dev_change_mtu(struct net_device *netdev, int mtu)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	struct airoha_eth *eth = port->qdma->eth;
>  	u32 len = ETH_HLEN + mtu + ETH_FCS_LEN;
>  
>  	airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
>  		      GDM_LONG_LEN_MASK,
>  		      FIELD_PREP(GDM_LONG_LEN_MASK, len));
> -	WRITE_ONCE(dev->mtu, mtu);
> +	WRITE_ONCE(netdev->mtu, mtu);
>  
>  	return 0;
>  }
>  
> -static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb,
> +static u16 airoha_dev_select_queue(struct net_device *netdev,
> +				   struct sk_buff *skb,
>  				   struct net_device *sb_dev)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	int queue, channel;
>  
>  	/* For dsa device select QoS channel according to the dsa user port
>  	 * index, rely on port id otherwise. Select QoS queue based on the
>  	 * skb priority.
>  	 */
> -	channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id;
> +	channel = netdev_uses_dsa(netdev) ? skb_get_queue_mapping(skb) : port->id;
>  	channel = channel % AIROHA_NUM_QOS_CHANNELS;
>  	queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */
>  	queue = channel * AIROHA_NUM_QOS_QUEUES + queue;
>  
> -	return queue < dev->num_tx_queues ? queue : 0;
> +	return queue < netdev->num_tx_queues ? queue : 0;
>  }
>  
>  static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev)
> @@ -1994,9 +2006,10 @@ int airoha_get_fe_port(struct airoha_gdm_port *port)
>  }
>  
>  static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
> -				   struct net_device *dev)
> +				   struct net_device *netdev)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	struct airoha_qdma *qdma = port->qdma;
>  	u32 nr_frags, tag, msg0, msg1, len;
>  	struct airoha_queue_entry *e;
> @@ -2009,7 +2022,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
>  	u8 fport;
>  
>  	qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb));
> -	tag = airoha_get_dsa_tag(skb, dev);
> +	tag = airoha_get_dsa_tag(skb, netdev);
>  
>  	msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK,
>  			  qid / AIROHA_NUM_QOS_QUEUES) |
> @@ -2045,7 +2058,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
>  
>  	spin_lock_bh(&q->lock);
>  
> -	txq = skb_get_tx_queue(dev, skb);
> +	txq = skb_get_tx_queue(netdev, skb);
>  	nr_frags = 1 + skb_shinfo(skb)->nr_frags;
>  
>  	if (q->queued + nr_frags >= q->ndesc) {
> @@ -2069,9 +2082,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
>  		dma_addr_t addr;
>  		u32 val;
>  
> -		addr = dma_map_single(dev->dev.parent, data, len,
> +		addr = dma_map_single(netdev->dev.parent, data, len,
>  				      DMA_TO_DEVICE);
> -		if (unlikely(dma_mapping_error(dev->dev.parent, addr)))
> +		if (unlikely(dma_mapping_error(netdev->dev.parent, addr)))
>  			goto error_unmap;
>  
>  		list_move_tail(&e->list, &tx_list);
> @@ -2120,7 +2133,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
>  
>  error_unmap:
>  	list_for_each_entry(e, &tx_list, list) {
> -		dma_unmap_single(dev->dev.parent, e->dma_addr, e->dma_len,
> +		dma_unmap_single(netdev->dev.parent, e->dma_addr, e->dma_len,
>  				 DMA_TO_DEVICE);
>  		e->dma_addr = 0;
>  	}
> @@ -2129,25 +2142,27 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
>  	spin_unlock_bh(&q->lock);
>  error:
>  	dev_kfree_skb_any(skb);
> -	dev->stats.tx_dropped++;
> +	netdev->stats.tx_dropped++;
>  
>  	return NETDEV_TX_OK;
>  }
>  
> -static void airoha_ethtool_get_drvinfo(struct net_device *dev,
> +static void airoha_ethtool_get_drvinfo(struct net_device *netdev,
>  				       struct ethtool_drvinfo *info)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	struct airoha_eth *eth = port->qdma->eth;
>  
>  	strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
>  	strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
>  }
>  
> -static void airoha_ethtool_get_mac_stats(struct net_device *dev,
> +static void airoha_ethtool_get_mac_stats(struct net_device *netdev,
>  					 struct ethtool_eth_mac_stats *stats)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	unsigned int start;
>  
>  	airoha_update_hw_stats(port);
> @@ -2175,11 +2190,12 @@ static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = {
>  };
>  
>  static void
> -airoha_ethtool_get_rmon_stats(struct net_device *dev,
> +airoha_ethtool_get_rmon_stats(struct net_device *netdev,
>  			      struct ethtool_rmon_stats *stats,
>  			      const struct ethtool_rmon_hist_range **ranges)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	struct airoha_hw_stats *hw_stats = &port->stats;
>  	unsigned int start;
>  
> @@ -2204,11 +2220,12 @@ airoha_ethtool_get_rmon_stats(struct net_device *dev,
>  	} while (u64_stats_fetch_retry(&port->stats.syncp, start));
>  }
>  
> -static int airoha_qdma_set_chan_tx_sched(struct net_device *dev,
> +static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
>  					 int channel, enum tx_sched_mode mode,
>  					 const u16 *weights, u8 n_weights)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	int i;
>  
>  	for (i = 0; i < AIROHA_NUM_TX_RING; i++)
> @@ -2293,10 +2310,12 @@ static int airoha_qdma_set_tx_ets_sched(struct net_device *dev, int channel,
>  					     ARRAY_SIZE(w));
>  }
>  
> -static int airoha_qdma_get_tx_ets_stats(struct net_device *dev, int channel,
> +static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,
>  					struct tc_ets_qopt_offload *opt)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
> +
>  	u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
>  					    REG_CNTR_VAL(channel << 1));
>  	u64 fwd_tx_packets = airoha_qdma_rr(port->qdma,
> @@ -2558,11 +2577,12 @@ static int airoha_qdma_set_trtcm_token_bucket(struct airoha_qdma *qdma,
>  					   mode, val);
>  }
>  
> -static int airoha_qdma_set_tx_rate_limit(struct net_device *dev,
> +static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,
>  					 int channel, u32 rate,
>  					 u32 bucket_size)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	int i, err;
>  
>  	for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
> @@ -2582,20 +2602,22 @@ static int airoha_qdma_set_tx_rate_limit(struct net_device *dev,
>  	return 0;
>  }
>  
> -static int airoha_tc_htb_alloc_leaf_queue(struct net_device *dev,
> +static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
>  					  struct tc_htb_qopt_offload *opt)
>  {
>  	u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
>  	u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */
> -	int err, num_tx_queues = dev->real_num_tx_queues;
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	int err, num_tx_queues = netdev->real_num_tx_queues;
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  
>  	if (opt->parent_classid != TC_HTB_CLASSID_ROOT) {
>  		NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid");
>  		return -EINVAL;
>  	}
>  
> -	err = airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum);
> +	err = airoha_qdma_set_tx_rate_limit(netdev, channel, rate,
> +					    opt->quantum);
>  	if (err) {
>  		NL_SET_ERR_MSG_MOD(opt->extack,
>  				   "failed configuring htb offload");
> @@ -2605,9 +2627,10 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *dev,
>  	if (opt->command == TC_HTB_NODE_MODIFY)
>  		return 0;
>  
> -	err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1);
> +	err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
>  	if (err) {
> -		airoha_qdma_set_tx_rate_limit(dev, channel, 0, opt->quantum);
> +		airoha_qdma_set_tx_rate_limit(netdev, channel, 0,
> +					      opt->quantum);
>  		NL_SET_ERR_MSG_MOD(opt->extack,
>  				   "failed setting real_num_tx_queues");
>  		return err;
> @@ -2697,11 +2720,12 @@ static int airoha_tc_matchall_act_validate(struct tc_cls_matchall_offload *f)
>  	return 0;
>  }
>  
> -static int airoha_dev_tc_matchall(struct net_device *dev,
> +static int airoha_dev_tc_matchall(struct net_device *netdev,
>  				  struct tc_cls_matchall_offload *f)
>  {
>  	enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT;
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	u32 rate = 0, bucket_size = 0;
>  
>  	switch (f->command) {
> @@ -2736,18 +2760,19 @@ static int airoha_dev_tc_matchall(struct net_device *dev,
>  static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type,
>  					void *type_data, void *cb_priv)
>  {
> -	struct net_device *dev = cb_priv;
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct net_device *netdev = cb_priv;
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	struct airoha_eth *eth = port->qdma->eth;
>  
> -	if (!tc_can_offload(dev))
> +	if (!tc_can_offload(netdev))
>  		return -EOPNOTSUPP;
>  
>  	switch (type) {
>  	case TC_SETUP_CLSFLOWER:
>  		return airoha_ppe_setup_tc_block_cb(&eth->ppe->dev, type_data);
>  	case TC_SETUP_CLSMATCHALL:
> -		return airoha_dev_tc_matchall(dev, type_data);
> +		return airoha_dev_tc_matchall(netdev, type_data);
>  	default:
>  		return -EOPNOTSUPP;
>  	}
> @@ -2794,47 +2819,51 @@ static int airoha_dev_setup_tc_block(struct net_device *dev,
>  	}
>  }
>  
> -static void airoha_tc_remove_htb_queue(struct net_device *dev, int queue)
> +static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  
> -	netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1);
> -	airoha_qdma_set_tx_rate_limit(dev, queue + 1, 0, 0);
> +	netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
> +	airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0);
>  	clear_bit(queue, port->qos_sq_bmap);
>  }
>  
> -static int airoha_tc_htb_delete_leaf_queue(struct net_device *dev,
> +static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
>  					   struct tc_htb_qopt_offload *opt)
>  {
>  	u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  
>  	if (!test_bit(channel, port->qos_sq_bmap)) {
>  		NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
>  		return -EINVAL;
>  	}
>  
> -	airoha_tc_remove_htb_queue(dev, channel);
> +	airoha_tc_remove_htb_queue(netdev, channel);
>  
>  	return 0;
>  }
>  
> -static int airoha_tc_htb_destroy(struct net_device *dev)
> +static int airoha_tc_htb_destroy(struct net_device *netdev)
>  {
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  	int q;
>  
>  	for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
> -		airoha_tc_remove_htb_queue(dev, q);
> +		airoha_tc_remove_htb_queue(netdev, q);
>  
>  	return 0;
>  }
>  
> -static int airoha_tc_get_htb_get_leaf_queue(struct net_device *dev,
> +static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev,
>  					    struct tc_htb_qopt_offload *opt)
>  {
>  	u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
> -	struct airoha_gdm_port *port = netdev_priv(dev);
> +	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
>  
>  	if (!test_bit(channel, port->qos_sq_bmap)) {
>  		NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
> @@ -2870,8 +2899,8 @@ static int airoha_tc_setup_qdisc_htb(struct net_device *dev,
>  	return 0;
>  }
>  
> -static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
> -			       void *type_data)
> +static int airoha_dev_tc_setup(struct net_device *dev,
> +			       enum tc_setup_type type, void *type_data)
>  {
>  	switch (type) {
>  	case TC_SETUP_QDISC_ETS:
> @@ -2937,25 +2966,81 @@ static void airoha_metadata_dst_free(struct airoha_gdm_port *port)
>  	}
>  }
>  
> -bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
> -			      struct airoha_gdm_port *port)
> +bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
> +			     struct airoha_gdm_dev *dev)
>  {
>  	int i;
>  
>  	for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
> -		if (eth->ports[i] == port)
> +		struct airoha_gdm_port *port = eth->ports[i];
> +
> +		if (!port)
> +			continue;
> +
> +		if (port->dev == dev)
>  			return true;
>  	}
>  
>  	return false;
>  }
>  
> +static int airoha_alloc_gdm_device(struct airoha_eth *eth,
> +				   struct airoha_gdm_port *port,
> +				   struct device_node *np)
> +{
> +	struct airoha_gdm_dev *dev;
> +	struct net_device *netdev;
> +	int err;
> +
> +	netdev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*dev),
> +					 AIROHA_NUM_NETDEV_TX_RINGS,
> +					 AIROHA_NUM_RX_RING);
> +	if (!netdev) {
> +		dev_err(eth->dev, "alloc_etherdev failed\n");
> +		return -ENOMEM;
> +	}
> +
> +	netdev->netdev_ops = &airoha_netdev_ops;
> +	netdev->ethtool_ops = &airoha_ethtool_ops;
> +	netdev->max_mtu = AIROHA_MAX_MTU;
> +	netdev->watchdog_timeo = 5 * HZ;
> +	netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO6 |
> +			      NETIF_F_IPV6_CSUM | NETIF_F_SG | NETIF_F_TSO |
> +			      NETIF_F_HW_TC;
> +	netdev->features |= netdev->hw_features;
> +	netdev->vlan_features = netdev->hw_features;
> +	netdev->dev.of_node = np;
> +	SET_NETDEV_DEV(netdev, eth->dev);
> +
> +	/* reserve hw queues for HTB offloading */
> +	err = netif_set_real_num_tx_queues(netdev, AIROHA_NUM_TX_RING);
> +	if (err)
> +		return err;
> +
> +	err = of_get_ethdev_address(np, netdev);
> +	if (err) {
> +		if (err == -EPROBE_DEFER)
> +			return err;
> +
> +		eth_hw_addr_random(netdev);
> +		dev_info(eth->dev, "generated random MAC address %pM\n",
> +			 netdev->dev_addr);
> +	}
> +
> +	dev = netdev_priv(netdev);
> +	dev->dev = netdev;
> +	dev->port = port;
> +	port->dev = dev;
> +	dev->eth = eth;
> +
> +	return 0;
> +}
> +
>  static int airoha_alloc_gdm_port(struct airoha_eth *eth,
>  				 struct device_node *np)
>  {
>  	const __be32 *id_ptr = of_get_property(np, "reg", NULL);
>  	struct airoha_gdm_port *port;
> -	struct net_device *dev;
>  	int err, p;
>  	u32 id;
>  
> @@ -2977,53 +3062,22 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
>  		return -EINVAL;
>  	}
>  
> -	dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port),
> -				      AIROHA_NUM_NETDEV_TX_RINGS,
> -				      AIROHA_NUM_RX_RING);
> -	if (!dev) {
> -		dev_err(eth->dev, "alloc_etherdev failed\n");
> +	port = devm_kzalloc(eth->dev, sizeof(*port), GFP_KERNEL);
> +	if (!port)
>  		return -ENOMEM;
> -	}
> -
> -	dev->netdev_ops = &airoha_netdev_ops;
> -	dev->ethtool_ops = &airoha_ethtool_ops;
> -	dev->max_mtu = AIROHA_MAX_MTU;
> -	dev->watchdog_timeo = 5 * HZ;
> -	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
> -			   NETIF_F_TSO6 | NETIF_F_IPV6_CSUM |
> -			   NETIF_F_SG | NETIF_F_TSO |
> -			   NETIF_F_HW_TC;
> -	dev->features |= dev->hw_features;
> -	dev->vlan_features = dev->hw_features;
> -	dev->dev.of_node = np;
> -	SET_NETDEV_DEV(dev, eth->dev);
> -
> -	/* reserve hw queues for HTB offloading */
> -	err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING);
> -	if (err)
> -		return err;
> -
> -	err = of_get_ethdev_address(np, dev);
> -	if (err) {
> -		if (err == -EPROBE_DEFER)
> -			return err;
> -
> -		eth_hw_addr_random(dev);
> -		dev_info(eth->dev, "generated random MAC address %pM\n",
> -			 dev->dev_addr);
> -	}
>  
> -	port = netdev_priv(dev);
>  	u64_stats_init(&port->stats.syncp);
>  	spin_lock_init(&port->stats.lock);
> -	port->eth = eth;
> -	port->dev = dev;
>  	port->id = id;
>  	/* XXX: Read nbq from DTS */
>  	port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
>  	eth->ports[p] = port;
>  
> -	return airoha_metadata_dst_alloc(port);
> +	err = airoha_metadata_dst_alloc(port);
> +	if (err)
> +		return err;
> +
> +	return airoha_alloc_gdm_device(eth, port, np);
>  }
>  
>  static int airoha_register_gdm_devices(struct airoha_eth *eth)
> @@ -3037,7 +3091,7 @@ static int airoha_register_gdm_devices(struct airoha_eth *eth)
>  		if (!port)
>  			continue;
>  
> -		err = register_netdev(port->dev);
> +		err = register_netdev(port->dev->dev);
>  		if (err)
>  			return err;
>  	}
> @@ -3146,12 +3200,14 @@ static int airoha_probe(struct platform_device *pdev)
>  
>  	for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
>  		struct airoha_gdm_port *port = eth->ports[i];
> +		struct airoha_gdm_dev *dev;
>  
>  		if (!port)
>  			continue;
>  
> -		if (port->dev->reg_state == NETREG_REGISTERED)
> -			unregister_netdev(port->dev);
> +		dev = port->dev;
> +		if (dev && dev->dev->reg_state == NETREG_REGISTERED)
> +			unregister_netdev(dev->dev);
>  		airoha_metadata_dst_free(port);
>  	}
>  	airoha_hw_cleanup(eth);
> @@ -3172,11 +3228,14 @@ static void airoha_remove(struct platform_device *pdev)
>  
>  	for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
>  		struct airoha_gdm_port *port = eth->ports[i];
> +		struct airoha_gdm_dev *dev;
>  
>  		if (!port)
>  			continue;
>  
> -		unregister_netdev(port->dev);
> +		dev = port->dev;
> +		if (dev)
> +			unregister_netdev(dev->dev);
>  		airoha_metadata_dst_free(port);
>  	}
>  	airoha_hw_cleanup(eth);
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
> index d3781103abb5..c78cabbec753 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.h
> +++ b/drivers/net/ethernet/airoha/airoha_eth.h
> @@ -535,10 +535,15 @@ struct airoha_qdma {
>  	struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
>  };
>  
> +struct airoha_gdm_dev {
> +	struct airoha_gdm_port *port;
> +	struct net_device *dev;
> +	struct airoha_eth *eth;
> +};
> +
>  struct airoha_gdm_port {
>  	struct airoha_qdma *qdma;
> -	struct airoha_eth *eth;
> -	struct net_device *dev;
> +	struct airoha_gdm_dev *dev;
>  	int id;
>  	int nbq;
>  
> @@ -662,8 +667,8 @@ static inline bool airoha_is_7583(struct airoha_eth *eth)
>  }
>  
>  int airoha_get_fe_port(struct airoha_gdm_port *port);
> -bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
> -			      struct airoha_gdm_port *port);
> +bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
> +			     struct airoha_gdm_dev *dev);
>  
>  void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id,
>  			     u8 fport);
> diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
> index 26da519236bf..af7af4097b98 100644
> --- a/drivers/net/ethernet/airoha/airoha_ppe.c
> +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
> @@ -298,12 +298,12 @@ static void airoha_ppe_foe_set_bridge_addrs(struct airoha_foe_bridge *br,
>  
>  static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
>  					struct airoha_foe_entry *hwe,
> -					struct net_device *dev, int type,
> +					struct net_device *netdev, int type,
>  					struct airoha_flow_data *data,
>  					int l4proto)
>  {
>  	u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val;
> -	int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&dev);
> +	int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&netdev);
>  	struct airoha_foe_mac_info_common *l2;
>  	u8 smac_id = 0xf;
>  
> @@ -319,10 +319,11 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
>  	hwe->ib1 = val;
>  
>  	val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f);
> -	if (dev) {
> +	if (netdev) {
>  		struct airoha_wdma_info info = {};
>  
> -		if (!airoha_ppe_get_wdma_info(dev, data->eth.h_dest, &info)) {
> +		if (!airoha_ppe_get_wdma_info(netdev, data->eth.h_dest,
> +					      &info)) {
>  			val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, info.idx) |
>  			       FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT,
>  					  FE_PSE_PORT_CDM4);
> @@ -332,12 +333,14 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
>  				     FIELD_PREP(AIROHA_FOE_MAC_WDMA_WCID,
>  						info.wcid);
>  		} else {
> -			struct airoha_gdm_port *port = netdev_priv(dev);
> +			struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +			struct airoha_gdm_port *port;
>  			u8 pse_port, channel;
>  
> -			if (!airoha_is_valid_gdm_port(eth, port))
> +			if (!airoha_is_valid_gdm_dev(eth, dev))
>  				return -EINVAL;
>  
> +			port = dev->port;
>  			if (dsa_port >= 0 || eth->ports[1])
>  				pse_port = port->id == 4 ? FE_PSE_PORT_GDM4
>  							 : port->id;
> @@ -1473,7 +1476,7 @@ void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
>  void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
>  {
>  	struct airoha_eth *eth = port->qdma->eth;
> -	struct net_device *dev = port->dev;
> +	struct net_device *dev = port->dev->dev;
>  	const u8 *addr = dev->dev_addr;
>  	u32 val;
>  
> 
> -- 
> 2.54.0
> 

Commenting on sashiko's report:
https://sashiko.dev/#/patchset/20260511-airoha-eth-multi-serdes-v6-0-c899462c4f75%40kernel.org

- This problem wasn't introduced by this patch, but does this function call lead
  to out-of-bounds memory accesses?
  - I do not think this is an issue, since airoha_eth driver supports just mtk as
    dsa driver where we actually skb_push() MTK_HDR_LEN bytes in mtk_tag_xmit().

- This problem wasn't introduced by this patch, but does this incorrect bounds
  accounting in HTB offload break QoS?
  - I will fix this issue with a dedicated patch.

- This problem wasn't introduced by this patch, but does this leave the rate
  limit active due to an off-by-one error?
  - I will fix this issue with a dedicated patch.

- This problem wasn't introduced by this patch, but does this lead to a
  use-after-free of the device tree node?
  - This is fixed by a subsequent patch in the series.

Regards,
Lorenzo

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [GIT PULL] KVM/arm64 fixes for 7.1, take #2
From: Paolo Bonzini @ 2026-05-12 21:15 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Alexandru Elisei, Catalin Marinas, Fuad Tabba, James Morse,
	Lorenzo Pieralisi, Mark Rutland, Mostafa Saleh, Oliver Upton,
	Sebastian Ott, Steffen Eiden, Sudeep Holla, Vincent Donnefort,
	Wei-Lin Chang, Will Deacon, Yuan Yao, Joey Gouly,
	Suzuki K Poulose, Zenghui Yu, kvmarm, linux-arm-kernel, kvm
In-Reply-To: <20260507154221.2905554-1-maz@kernel.org>

On Thu, May 7, 2026 at 5:42 PM Marc Zyngier <maz@kernel.org> wrote:
>
> Paolo,
>
> Here's the second set of KVM/arm64 fixes for 7.1. Nothing too horrible
> this time, aside from an ARM erratum workaround that has little impact
> on KVM, but relies on some firmware dealing with the problem. Bleh.
>
> The rest is a small collection of bug fixes, mostly affecting the MMU
> (permission fault handling with guest_memfd, 52bit VA with NV), and a
> small set of AI-enhanced fixes from Fuad. I guess I'll have to get
> used to that.
>
> And last but not least, Steffen joins the merry band of KVM/arm64
> reviewers in preparation of s390 and arm64 being joined at the hip...
>
> Please pull,

Done, thanks.

Paolo

>
>         M.
>
> The following changes since commit 7fd2df204f342fc17d1a0bfcd474b24232fb0f32:
>
>   Linux 7.1-rc2 (2026-05-03 14:21:25 -0700)
>
> are available in the Git repository at:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git kvmarm-fixes-7.1-2
>
> for you to fetch changes up to effc0a39b8e0f30670fe24f51e44329d4324e566:
>
>   KVM: arm64: Pre-check vcpu memcache for host->guest donate (2026-05-07 14:12:42 +0100)
>
> ----------------------------------------------------------------
> KVM/arm64 fixes for 7.1, take #2
>
> - Add the pKVM side of the workaround for ARM's erratum 4193714, provided
>   that the EL3 firmware does its part of the job. KVM will refuse to
>   initialise otherwise.
>
> - Correctly handle 52bit VAs for guest EL2 stage-1 translations when
>   running under NV with E2H==0.
>
> - Correctly deal with permission faults in guest_memfd memslots.
>
> - Fix the steal-time selftest after the infrastructure was reworked.
>
> - Make sure the host cannot pass a non-sensical clock update to the
>   EL2 tracing infrastructure.
>
> - Appoint Steffen Eiden as a reviewer in anticipation of the KVM/s390
>   ability to run arm64 guests, which will inevitably lead to arm64
>   code being directly used on s390.
>
> - Make sure that EL2 is configured with both exception entry and exit
>   being Context Synchronization Events.
>
> - Handle the current vcpu being NULL on EL2 panic.
>
> - Fix the selftest_vcpu memcache being empty at the point of donation or
>   sharing.
>
> - Check that the memcache has enough capacity before engaging on the
>   share/donate path.
>
> - Fix __deactivate_fgt() to use its parameter rather than a variable
>   in the macro context.
>
> ----------------------------------------------------------------
> Alexandru Elisei (1):
>       KVM: arm64: Handle permission faults with guest_memfd
>
> Fuad Tabba (6):
>       KVM: arm64: Make EL2 exception entry and exit context-synchronization events
>       KVM: arm64: Guard against NULL vcpu on VHE hyp panic path
>       KVM: arm64: Fix __deactivate_fgt macro parameter typo
>       KVM: arm64: Seed pkvm_ownership_selftest vcpu memcache
>       KVM: arm64: Pre-check vcpu memcache for host->guest share
>       KVM: arm64: Pre-check vcpu memcache for host->guest donate
>
> James Morse (1):
>       KVM: arm64: Work around C1-Pro erratum 4193714 for protected guests
>
> Mostafa Saleh (1):
>       KVM: arm64: Remove potential UB on nvhe tracing clock update
>
> Sebastian Ott (1):
>       KVM: selftests: arm64: Fix steal_time test after UAPI refactoring
>
> Steffen Eiden (1):
>       MAINTAINERS: Add Steffen as reviewer for KVM/arm64
>
> Wei-Lin Chang (1):
>       KVM: arm64: nv: Consider the DS bit when translating TCR_EL2
>
>  MAINTAINERS                              |  1 +
>  arch/arm64/include/asm/kvm_nested.h      |  1 +
>  arch/arm64/include/asm/sysreg.h          |  2 +-
>  arch/arm64/kvm/arm.c                     | 21 ++++++++++++++
>  arch/arm64/kvm/hyp/include/hyp/switch.h  |  2 +-
>  arch/arm64/kvm/hyp/nvhe/clock.c          |  3 ++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c    | 47 +++++++++++++++++++++++++++++++-
>  arch/arm64/kvm/hyp/nvhe/pkvm.c           | 16 ++++++++++-
>  arch/arm64/kvm/hyp/vhe/switch.c          |  3 +-
>  arch/arm64/kvm/mmu.c                     | 29 ++++++++++++++------
>  include/linux/arm-smccc.h                |  6 ++++
>  tools/testing/selftests/kvm/steal_time.c |  2 ++
>  12 files changed, 120 insertions(+), 13 deletions(-)
>



^ permalink raw reply

* Re: [PATCH net-next v6 11/12] net: airoha: Support multiple LAN/WAN interfaces for hw MAC address configuration
From: Lorenzo Bianconi @ 2026-05-12 20:58 UTC (permalink / raw)
  To: Benjamin Larsson
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Christian Marangi, linux-arm-kernel, linux-mediatek, netdev,
	devicetree, Madhur Agrawal
In-Reply-To: <f4a11830-8a3f-4cc3-ab82-e6f02ca34ae8@genexis.eu>

[-- Attachment #1: Type: text/plain, Size: 3464 bytes --]

On May 12, Benjamin Larsson wrote:
> Hi.
> 
> On 11/05/2026 12:49, Lorenzo Bianconi wrote:
> > The EN7581 and AN7583 SoCs provide registers to configure hardware LAN/WAN
> > MAC addresses, used to determine whether received traffic is destined for
> > this host or should be forwarded to another device.
> > The SoC hardware design assumes all interfaces configured as LAN (or WAN)
> > share a common upper MAC address, which is programmed into the
> > REG_FE_{LAN,WAN}_MAC_H register. The lower bytes of 'local' addresses can
> > be expressed as a range via the REG_FE_MAC_LMIN and REG_FE_MAC_LMAX
> > registers.
> > Previously, only a single interface was considered when programming these
> > registers. Extend the logic to derive the correct minimum and maximum
> > values for REG_FE_MAC_LMIN/REG_FE_MAC_LMAX when two or more interfaces are
> > configured as LAN or WAN.
> > 
> > Tested-by: Madhur Agrawal <madhur.agrawal@airoha.com>
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> >   drivers/net/ethernet/airoha/airoha_eth.c | 75 +++++++++++++++++++++++++++-----
> >   drivers/net/ethernet/airoha/airoha_eth.h |  2 +-
> >   drivers/net/ethernet/airoha/airoha_ppe.c |  4 +-
> >   3 files changed, 66 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> > index 16c0ff9999da..533ffe20f833 100644
> > --- a/drivers/net/ethernet/airoha/airoha_eth.c
> > +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> > @@ -71,20 +71,67 @@ static void airoha_qdma_irq_disable(struct airoha_irq_bank *irq_bank,
> >   	airoha_qdma_set_irqmask(irq_bank, index, mask, 0);
> >   }
> > -static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
> > +static int airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
> >   {
> >   	struct airoha_eth *eth = dev->eth;
> > -	u32 val, reg;
> > +	u8 ref_addr[ETH_ALEN] = {};
> > +	u32 reg, val, lmin, lmax;
> > +	int i;
> > +
> > +	lmin = (addr[3] << 16) | (addr[4] << 8) | addr[5];
> > +	lmax = lmin;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
> > +		struct airoha_gdm_port *port = eth->ports[i];
> > +		int j;
> > +
> > +		if (!port)
> > +			continue;
> > +
> > +		for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
> > +			struct airoha_gdm_dev *iter_dev;
> > +			struct net_device *netdev;
> > +
> > +			iter_dev = port->devs[j];
> > +			if (!iter_dev || iter_dev == dev)
> > +				continue;
> > +
> > +			if (airoha_is_lan_gdm_dev(iter_dev) !=
> > +			    airoha_is_lan_gdm_dev(dev))
> > +				continue;
> > +
> > +			netdev = iter_dev->dev;
> > +			if (netdev->reg_state != NETREG_REGISTERED)
> > +				continue;
> > +
> > +			ether_addr_copy(ref_addr, netdev->dev_addr);
> > +			val = (netdev->dev_addr[3] << 16) |
> > +			      (netdev->dev_addr[4] << 8) | netdev->dev_addr[5];
> > +			if (val < lmin)
> > +				lmin = val;
> > +			if (val > lmax)
> > +				lmax = val;
> > +		}
> > +	}
> > +
> > +	if (!is_zero_ether_addr(ref_addr) && memcmp(ref_addr, addr, 3)) {
> > +		/* According to the HW design, hw mac address MS bits
> > +		 * must be the same for each net_device with the same
> > +		 * LAN/WAN configuration.
> > +		 */
> > +		return -EINVAL;
> > +	}
> 
> Maybe this information should be relayed to the user somehow?

netdev_err()?

Regards,
Lorenzo

> 
> MvH
> 
> Benjamin Larsson
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v3] dt-bindings: iio: adc: Convert xilinx-xadc bindings to YAML schema
From: Rob Herring @ 2026-05-12 20:48 UTC (permalink / raw)
  To: David Lechner
  Cc: Pramod Maurya, Jonathan Cameron, Nuno Sá, Andy Shevchenko,
	Krzysztof Kozlowski, Conor Dooley, Michal Simek,
	Lars-Peter Clausen, linux-iio, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <5a02550a-a578-4c0b-a8b0-2056f0248478@baylibre.com>

On Tue, May 12, 2026 at 3:03 PM David Lechner <dlechner@baylibre.com> wrote:
>
> On 5/12/26 2:42 PM, Rob Herring wrote:
> > On Tue, May 12, 2026 at 8:58 AM David Lechner <dlechner@baylibre.com> wrote:
> >>
> >> On 5/12/26 7:14 AM, Rob Herring wrote:
> >>> On Mon, May 11, 2026 at 11:24 AM David Lechner <dlechner@baylibre.com> wrote:
> >>>>
> >>>> On 5/11/26 11:15 AM, Jonathan Cameron wrote:
> >>>>> On Sun, 10 May 2026 08:01:36 -0400
> >>>>> Pramod Maurya <pramod.nexgen@gmail.com> wrote:
> >>>>>
> >>>>>> Convert the Xilinx XADC and UltraScale System Monitor device tree binding
> >>>>>> from the legacy plain-text format to a YAML schema, enabling automated
> >>>>>> validation with dt-schema.
> >>>>>>
> >>>>>> The new binding covers the same hardware and compatible strings:
> >>>>>>   - xlnx,zynq-xadc-1.00.a (ZYNQ hardmacro)
> >>>>>>   - xlnx,axi-xadc-1.00.a  (AXI softmacro)
> >>>>>>   - xlnx,system-management-wiz-1.3 (UltraScale System Management Wizard)
> >>>>>>
> >>>>>> Signed-off-by: Pramod Maurya <pramod.nexgen@gmail.com>
> >>>>> Hi Pramod,
> >>>>>
> >>>>> Something went wrong with your sending of v3. I have two versions sent
> >>>>> half a day apart and no idea how they are related.
> >>>>>
> >>>>> Anyhow one of them got feedback from Rob's bot so I'll assume we are
> >>>>> getting a v4 and wait for that.
> >>>>>
> >>>>> Jonathan
> >>>>
> >>>> I think Rob will have to fix the bot to make an exception for the
> >>>> legacy bindings. This should have been called out in the commit message
> >>>> as requested in a previous revision.
> >>>
> >>> The bot is not the problem. It just runs validation. The schemas will
> >>> have to either drop this check (comma's in nodenames) or exclude just
> >>> this property.
> >>>
> >>>
> >>> Rob
> >>
> >> Even though this is an existing text-based schema that has been around
> >> for 12 years with this name already? Changing it could be a breaking
> >> change to existing users. Although there aren't any in any .dts in the
> >> kernel source.
> >
> > I'm absolutely not suggesting changing the node name.
> >
> > The common schemas globally disallow commas in nodenames. We can relax
> > that and allow commas in any nodename. That check is largely from
> > QCom's amazingly consistent use of 'qcom' prefix in nodenames. We've
> > finally beat that practice out of them. So maybe it's not needed
> > anymore.
> >
> > The other approach is to exclude this nodename and any other we have
> > to keep. I don't like dtschema having to know about some random name,
> > but we already have that in a few cases and I don't expect that list
> > to be too long given this is the first case we've seen.
> >
> > Rob
>
> Got it. So when I said "fix the bot" earlier, I should have said
> "fix dtschema". We went through this before with adi,channels, but
> I didn't remember exactly what you did.

Completely forgot that. That makes picking which one easy...

> I created a pull request for dt-schema [1] for this since it was
> easier than trying to explain it for someone else to do.
>
> [1]: https://github.com/devicetree-org/dt-schema/pull/195

Thank you! Applied.

Rob


^ permalink raw reply

* [PATCH] PCI: mvebu: Use fixed-width interrupt masks
From: Rosen Penev @ 2026-05-12 20:44 UTC (permalink / raw)
  To: linux-pci
  Cc: Thomas Petazzoni, Pali Rohár, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas

Use u32-typed BIT and GENMASK helpers for PCIe interrupt register
masks.  This keeps inverted masks in the same width as the registers
and avoids truncation warnings on 64-bit compile-test builds.

Drop the unused sys_to_pcie() helper while touching the same area; it
references stale ARM pci_sys_data glue and has no callers.

Assisted-by: Codex:GPT-5.5
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 drivers/pci/controller/pci-mvebu.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index e568528bad85..da43661792e8 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -57,9 +57,9 @@
 #define PCIE_CONF_DATA_OFF	0x18fc
 #define PCIE_INT_CAUSE_OFF	0x1900
 #define PCIE_INT_UNMASK_OFF	0x1910
-#define  PCIE_INT_INTX(i)		BIT(24+i)
-#define  PCIE_INT_PM_PME		BIT(28)
-#define  PCIE_INT_ALL_MASK		GENMASK(31, 0)
+#define  PCIE_INT_INTX(i)		BIT_U32(24 + (i))
+#define  PCIE_INT_PM_PME		BIT_U32(28)
+#define  PCIE_INT_ALL_MASK		GENMASK_U32(31, 0)
 #define PCIE_CTRL_OFF		0x1a00
 #define  PCIE_CTRL_X1_MODE		0x0001
 #define  PCIE_CTRL_RC_MODE		BIT(1)
@@ -950,11 +950,6 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 	return pci_bridge_emul_init(bridge, bridge_flags);
 }
 
-static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys)
-{
-	return sys->private_data;
-}
-
 static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
 						    struct pci_bus *bus,
 						    int devfn)
-- 
2.54.0



^ permalink raw reply related

* Re: [PATCH net-next v6 02/12] net: airoha: Reserve RX headroom to avoid skb reallocation
From: Lorenzo Bianconi @ 2026-05-12 20:31 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Christian Marangi, Benjamin Larsson, linux-arm-kernel,
	linux-mediatek, netdev, devicetree, Xuegang Lu
In-Reply-To: <20260511-airoha-eth-multi-serdes-v6-2-c899462c4f75@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 3105 bytes --]

On May 11, Lorenzo Bianconi wrote:
> Reserve NET_SKB_PAD + NET_IP_ALIGN bytes of headroom for received packets
> to avoid skb head reallocation when pushing protocol headers into the skb.
> 
> Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  drivers/net/ethernet/airoha/airoha_eth.c | 12 ++++++++----
>  drivers/net/ethernet/airoha/airoha_eth.h |  2 ++
>  2 files changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> index f71fb18197ec..3fe2561c85f1 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.c
> +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> @@ -543,9 +543,10 @@ static int airoha_qdma_fill_rx_queue(struct airoha_queue *q)
>  		q->queued++;
>  		nframes++;
>  
> +		offset += AIROHA_RX_HEADROOM;
>  		e->buf = page_address(page) + offset;
>  		e->dma_addr = page_pool_get_dma_addr(page) + offset;
> -		e->dma_len = SKB_WITH_OVERHEAD(q->buf_size);
> +		e->dma_len = SKB_WITH_OVERHEAD(AIROHA_RX_LEN(q->buf_size));
>  
>  		val = FIELD_PREP(QDMA_DESC_LEN_MASK, e->dma_len);
>  		WRITE_ONCE(desc->ctrl, cpu_to_le32(val));
> @@ -616,8 +617,9 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
>  
>  		page = virt_to_head_page(e->buf);
>  		len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl);
> -		data_len = q->skb ? q->buf_size
> -				  : SKB_WITH_OVERHEAD(q->buf_size);
> +		data_len = q->skb
> +			   ? AIROHA_RX_LEN(q->buf_size)
> +			   : SKB_WITH_OVERHEAD(AIROHA_RX_LEN(q->buf_size));
>  		if (!len || data_len < len)
>  			goto free_frag;
>  
> @@ -627,10 +629,12 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
>  
>  		port = eth->ports[p];
>  		if (!q->skb) { /* first buffer */
> -			q->skb = napi_build_skb(e->buf, q->buf_size);
> +			q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM,
> +						q->buf_size);
>  			if (!q->skb)
>  				goto free_frag;
>  
> +			skb_reserve(q->skb, AIROHA_RX_HEADROOM);
>  			__skb_put(q->skb, len);
>  			skb_mark_for_recycle(q->skb);
>  			q->skb->dev = port->dev;
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
> index 58530d096de7..d3781103abb5 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.h
> +++ b/drivers/net/ethernet/airoha/airoha_eth.h
> @@ -32,6 +32,8 @@
>  #define AIROHA_FE_MC_MAX_VLAN_TABLE	64
>  #define AIROHA_FE_MC_MAX_VLAN_PORT	16
>  #define AIROHA_NUM_TX_IRQ		2
> +#define AIROHA_RX_HEADROOM		(NET_SKB_PAD + NET_IP_ALIGN)
> +#define AIROHA_RX_LEN(_n)		((_n) - AIROHA_RX_HEADROOM)
>  #define HW_DSCP_NUM			2048
>  #define IRQ_QUEUE_LEN(_n)		((_n) ? 1024 : 2048)
>  #define TX_DSCP_NUM			1024
> 
> -- 
> 2.54.0
> 

commenting on sashiko's report:
https://sashiko.dev/#/patchset/20260511-airoha-eth-multi-serdes-v6-0-c899462c4f75%40kernel.org

- Does the length passed to dma_sync_single_for_cpu() also need to be updated
  to match the new DMA length?
  I will fix it in v7.

Regards,
Lorenzo

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH 1/1] dt-bindings: display: imx: add deprecated property 'port' and 'display-timings'
From: Conor Dooley @ 2026-05-12 20:25 UTC (permalink / raw)
  To: Frank Li
  Cc: Philipp Zabel, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam,
	open list:DRM DRIVERS FOR FREESCALE IMX 5/6,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	open list
In-Reply-To: <agNvt9RbRFQ395uE@lizhi-Precision-Tower-5810>

[-- Attachment #1: Type: text/plain, Size: 2443 bytes --]

On Tue, May 12, 2026 at 02:21:43PM -0400, Frank Li wrote:
> On Tue, May 12, 2026 at 05:47:11PM +0100, Conor Dooley wrote:
> > On Mon, May 11, 2026 at 06:09:24PM -0400, Frank Li wrote:
> > > Add deprecated property 'port' and 'display-timings' for i.MX5 SoCs (over
> > > 15 years) to fix below CHECK_DTBS warnings:
> > >   arm/boot/dts/nxp/imx/imx51-apf51dev.dtb: disp1 (fsl,imx-parallel-display): 'display-timings', 'port' do not match any of the regexes: '^pinctrl-[0-9]+$'
> > >         from schema $id: http://devicetree.org/schemas/display/imx/fsl,imx-parallel-display.yaml
> >
> > Instead of documenting the deprecated properties, could this
> > device/devicetree be converted to non-deprecated properties?
> 
> Change dts will cause break back compatiblity. This is too old chips and

How would changing the dts impact backwards compatibility? That argument
doesn't make sense to me, I am of course not suggesting removing support
from these properties from the driver.

I do accept that the argument of lacking info on the panel.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable

> I have not information panel's detail information.
> 
> Frank
> 
> >
> > >
> > > Signed-off-by: Frank Li <Frank.Li@nxp.com>
> > > ---
> > >  .../display/imx/fsl,imx-parallel-display.yaml         | 11 +++++++++++
> > >  1 file changed, 11 insertions(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx-parallel-display.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx-parallel-display.yaml
> > > index bbcfe7e2958b7..b0c5869771fae 100644
> > > --- a/Documentation/devicetree/bindings/display/imx/fsl,imx-parallel-display.yaml
> > > +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx-parallel-display.yaml
> > > @@ -42,6 +42,17 @@ properties:
> > >      unevaluatedProperties: false
> > >      description: output port connected to a panel
> > >
> > > +  port:
> > > +    $ref: /schemas/graph.yaml#/properties/port
> > > +    unevaluatedProperties: false
> > > +    deprecated: true
> > > +    description: input port connected to the IPU display interface, see port@0
> > > +
> > > +  display-timings:
> > > +    $ref: /schemas/display/panel/display-timings.yaml#
> > > +    unevaluatedProperties: false
> > > +    deprecated: true
> > > +
> > >  required:
> > >    - compatible
> > >
> > > --
> > > 2.43.0
> > >
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v3] dt-bindings: iio: adc: Convert xilinx-xadc bindings to YAML schema
From: David Lechner @ 2026-05-12 20:03 UTC (permalink / raw)
  To: Rob Herring, Pramod Maurya
  Cc: Jonathan Cameron, Nuno Sá, Andy Shevchenko,
	Krzysztof Kozlowski, Conor Dooley, Michal Simek,
	Lars-Peter Clausen, linux-iio, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <CAL_JsqKP-C-rA6_19vtMzevVxQiD7bH=k5ObEZZDM3-Zmr_vtg@mail.gmail.com>

On 5/12/26 2:42 PM, Rob Herring wrote:
> On Tue, May 12, 2026 at 8:58 AM David Lechner <dlechner@baylibre.com> wrote:
>>
>> On 5/12/26 7:14 AM, Rob Herring wrote:
>>> On Mon, May 11, 2026 at 11:24 AM David Lechner <dlechner@baylibre.com> wrote:
>>>>
>>>> On 5/11/26 11:15 AM, Jonathan Cameron wrote:
>>>>> On Sun, 10 May 2026 08:01:36 -0400
>>>>> Pramod Maurya <pramod.nexgen@gmail.com> wrote:
>>>>>
>>>>>> Convert the Xilinx XADC and UltraScale System Monitor device tree binding
>>>>>> from the legacy plain-text format to a YAML schema, enabling automated
>>>>>> validation with dt-schema.
>>>>>>
>>>>>> The new binding covers the same hardware and compatible strings:
>>>>>>   - xlnx,zynq-xadc-1.00.a (ZYNQ hardmacro)
>>>>>>   - xlnx,axi-xadc-1.00.a  (AXI softmacro)
>>>>>>   - xlnx,system-management-wiz-1.3 (UltraScale System Management Wizard)
>>>>>>
>>>>>> Signed-off-by: Pramod Maurya <pramod.nexgen@gmail.com>
>>>>> Hi Pramod,
>>>>>
>>>>> Something went wrong with your sending of v3. I have two versions sent
>>>>> half a day apart and no idea how they are related.
>>>>>
>>>>> Anyhow one of them got feedback from Rob's bot so I'll assume we are
>>>>> getting a v4 and wait for that.
>>>>>
>>>>> Jonathan
>>>>
>>>> I think Rob will have to fix the bot to make an exception for the
>>>> legacy bindings. This should have been called out in the commit message
>>>> as requested in a previous revision.
>>>
>>> The bot is not the problem. It just runs validation. The schemas will
>>> have to either drop this check (comma's in nodenames) or exclude just
>>> this property.
>>>
>>>
>>> Rob
>>
>> Even though this is an existing text-based schema that has been around
>> for 12 years with this name already? Changing it could be a breaking
>> change to existing users. Although there aren't any in any .dts in the
>> kernel source.
> 
> I'm absolutely not suggesting changing the node name.
> 
> The common schemas globally disallow commas in nodenames. We can relax
> that and allow commas in any nodename. That check is largely from
> QCom's amazingly consistent use of 'qcom' prefix in nodenames. We've
> finally beat that practice out of them. So maybe it's not needed
> anymore.
> 
> The other approach is to exclude this nodename and any other we have
> to keep. I don't like dtschema having to know about some random name,
> but we already have that in a few cases and I don't expect that list
> to be too long given this is the first case we've seen.
> 
> Rob

Got it. So when I said "fix the bot" earlier, I should have said
"fix dtschema". We went through this before with adi,channels, but
I didn't remember exactly what you did.

I created a pull request for dt-schema [1] for this since it was
easier than trying to explain it for someone else to do.

[1]: https://github.com/devicetree-org/dt-schema/pull/195





^ permalink raw reply

* Re: [PATCH v3] dt-bindings: iio: adc: Convert xilinx-xadc bindings to YAML schema
From: Rob Herring @ 2026-05-12 19:42 UTC (permalink / raw)
  To: David Lechner
  Cc: Jonathan Cameron, Pramod Maurya, Nuno Sá, Andy Shevchenko,
	Krzysztof Kozlowski, Conor Dooley, Michal Simek,
	Lars-Peter Clausen, linux-iio, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <a4ecfb27-5ef4-4682-b87c-24917f81b4f0@baylibre.com>

On Tue, May 12, 2026 at 8:58 AM David Lechner <dlechner@baylibre.com> wrote:
>
> On 5/12/26 7:14 AM, Rob Herring wrote:
> > On Mon, May 11, 2026 at 11:24 AM David Lechner <dlechner@baylibre.com> wrote:
> >>
> >> On 5/11/26 11:15 AM, Jonathan Cameron wrote:
> >>> On Sun, 10 May 2026 08:01:36 -0400
> >>> Pramod Maurya <pramod.nexgen@gmail.com> wrote:
> >>>
> >>>> Convert the Xilinx XADC and UltraScale System Monitor device tree binding
> >>>> from the legacy plain-text format to a YAML schema, enabling automated
> >>>> validation with dt-schema.
> >>>>
> >>>> The new binding covers the same hardware and compatible strings:
> >>>>   - xlnx,zynq-xadc-1.00.a (ZYNQ hardmacro)
> >>>>   - xlnx,axi-xadc-1.00.a  (AXI softmacro)
> >>>>   - xlnx,system-management-wiz-1.3 (UltraScale System Management Wizard)
> >>>>
> >>>> Signed-off-by: Pramod Maurya <pramod.nexgen@gmail.com>
> >>> Hi Pramod,
> >>>
> >>> Something went wrong with your sending of v3. I have two versions sent
> >>> half a day apart and no idea how they are related.
> >>>
> >>> Anyhow one of them got feedback from Rob's bot so I'll assume we are
> >>> getting a v4 and wait for that.
> >>>
> >>> Jonathan
> >>
> >> I think Rob will have to fix the bot to make an exception for the
> >> legacy bindings. This should have been called out in the commit message
> >> as requested in a previous revision.
> >
> > The bot is not the problem. It just runs validation. The schemas will
> > have to either drop this check (comma's in nodenames) or exclude just
> > this property.
> >
> >
> > Rob
>
> Even though this is an existing text-based schema that has been around
> for 12 years with this name already? Changing it could be a breaking
> change to existing users. Although there aren't any in any .dts in the
> kernel source.

I'm absolutely not suggesting changing the node name.

The common schemas globally disallow commas in nodenames. We can relax
that and allow commas in any nodename. That check is largely from
QCom's amazingly consistent use of 'qcom' prefix in nodenames. We've
finally beat that practice out of them. So maybe it's not needed
anymore.

The other approach is to exclude this nodename and any other we have
to keep. I don't like dtschema having to know about some random name,
but we already have that in a few cases and I don't expect that list
to be too long given this is the first case we've seen.

Rob


^ permalink raw reply

* [PATCH v4 6/6] arm64: dts: qcom: glymur: Add GPU cooling
From: Akhil P Oommen @ 2026-05-12 19:21 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Rob Clark, Sean Paul, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Will Deacon, Robin Murphy, Joerg Roedel
  Cc: linux-arm-msm, devicetree, linux-kernel, dri-devel, freedreno,
	linux-arm-kernel, iommu, Akhil P Oommen,
	Manaf Meethalavalappu Pallikunhi
In-Reply-To: <20260513-glymur-gpu-dt-v4-0-f83832c3bc9a@oss.qualcomm.com>

From: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

The GPU does not throttle its speed automatically when it
reaches high temperatures. Set up GPU cooling by throttling
the GPU speed when it reaches 95°C.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/glymur.dtsi | 240 +++++++++++++++++++++++++++--------
 1 file changed, 184 insertions(+), 56 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi
index 01a2e32e503b..e109fb5b35a4 100644
--- a/arch/arm64/boot/dts/qcom/glymur.dtsi
+++ b/arch/arm64/boot/dts/qcom/glymur.dtsi
@@ -22,6 +22,7 @@
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 #include <dt-bindings/soc/qcom,rpmh-rsc.h>
 #include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/thermal/thermal.h>
 
 #include "glymur-ipcc.h"
 
@@ -7149,13 +7150,22 @@ aoss-7-critical {
 		};
 
 		thermal_gpu_0_0: gpu-0-0-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 1>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu00_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu00_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-0-0-critical {
@@ -7164,16 +7174,26 @@ gpu-0-0-critical {
 					type = "critical";
 				};
 			};
+
 		};
 
 		thermal_gpu_0_1: gpu-0-1-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 2>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu01_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu01_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-0-1-critical {
@@ -7185,13 +7205,22 @@ gpu-0-1-critical {
 		};
 
 		thermal_gpu_0_2: gpu-0-2-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 3>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu02_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu02_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-0-2-critical {
@@ -7203,13 +7232,22 @@ gpu-0-2-critical {
 		};
 
 		thermal_gpu_1_0: gpu-1-0-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 4>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu10_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu10_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-1-0-critical {
@@ -7221,13 +7259,22 @@ gpu-1-0-critical {
 		};
 
 		thermal_gpu_1_1: gpu-1-1-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 5>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu11_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu11_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-1-1-critical {
@@ -7239,13 +7286,22 @@ gpu-1-1-critical {
 		};
 
 		thermal_gpu_1_2: gpu-1-2-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 6>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu12_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu12_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-1-2-critical {
@@ -7257,13 +7313,22 @@ gpu-1-2-critical {
 		};
 
 		thermal_gpu_2_0: gpu-2-0-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 7>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu20_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu20_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-2-0-critical {
@@ -7275,13 +7340,22 @@ gpu-2-0-critical {
 		};
 
 		thermal_gpu_2_1: gpu-2-1-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 8>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu21_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu21_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-2-1-critical {
@@ -7293,13 +7367,22 @@ gpu-2-1-critical {
 		};
 
 		thermal_gpu_2_2: gpu-2-2-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 9>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu22_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu22_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-2-2-critical {
@@ -7311,13 +7394,22 @@ gpu-2-2-critical {
 		};
 
 		thermal_gpu_3_0: gpu-3-0-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 10>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu30_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu30_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-3-0-critical {
@@ -7329,13 +7421,22 @@ gpu-3-0-critical {
 		};
 
 		thermal_gpu_3_1: gpu-3-1-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 11>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu31_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu31_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-3-1-critical {
@@ -7347,13 +7448,22 @@ gpu-3-1-critical {
 		};
 
 		thermal_gpu_3_2: gpu-3-2-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 12>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpu32_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpu32_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpu-3-2-critical {
@@ -7365,13 +7475,22 @@ gpu-3-2-critical {
 		};
 
 		thermal_gpuss_0: gpuss-0-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 13>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpuss0_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpuss0_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpuss-0-critical {
@@ -7383,13 +7502,22 @@ gpuss-0-critical {
 		};
 
 		thermal_gpuss_1: gpuss-1-thermal {
+			polling-delay-passive = <100>;
+
 			thermal-sensors = <&tsens7 14>;
 
+			cooling-maps {
+				map0 {
+					trip = <&gpuss1_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
 			trips {
-				trip-point0 {
-					temperature = <90000>;
-					hysteresis = <5000>;
-					type = "hot";
+				gpuss1_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
 				};
 
 				gpuss-1-critical {

-- 
2.51.0



^ permalink raw reply related

* [PATCH v4 5/6] arm64: dts: qcom: Add GPU support for Glymur
From: Akhil P Oommen @ 2026-05-12 19:21 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Rob Clark, Sean Paul, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Will Deacon, Robin Murphy, Joerg Roedel
  Cc: linux-arm-msm, devicetree, linux-kernel, dri-devel, freedreno,
	linux-arm-kernel, iommu, Akhil P Oommen, Konrad Dybcio
In-Reply-To: <20260513-glymur-gpu-dt-v4-0-f83832c3bc9a@oss.qualcomm.com>

The Adreno X2 series GPU present in Glymur SoC belongs to the A8x
family. It is a new HW IP with architectural improvements as well
as different set of hw configs like GMEM, num SPs, Caches sizes etc.

Add the GPU and GMU nodes to describe this hardware.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/glymur.dtsi | 183 +++++++++++++++++++++++++++++++++++
 1 file changed, 183 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi
index 5e76a0d53f01..01a2e32e503b 100644
--- a/arch/arm64/boot/dts/qcom/glymur.dtsi
+++ b/arch/arm64/boot/dts/qcom/glymur.dtsi
@@ -3701,6 +3701,129 @@ hsc_noc: interconnect@2000000 {
 			#interconnect-cells = <2>;
 		};
 
+		gpu: gpu@3d00000 {
+			compatible = "qcom,adreno-44070001", "qcom,adreno";
+			reg = <0x0 0x03d00000 0x0 0x6c000>,
+			      <0x0 0x03d9e000 0x0 0x2000>;
+			reg-names = "kgsl_3d0_reg_memory",
+				    "cx_mem";
+
+			interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+
+			iommus = <&adreno_smmu 0 0x0>,
+				 <&adreno_smmu 1 0x0>;
+
+			operating-points-v2 = <&gpu_opp_table>;
+
+			qcom,gmu = <&gmu>;
+			#cooling-cells = <2>;
+
+			interconnects = <&hsc_noc MASTER_GFX3D QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "gfx-mem";
+
+			gpu_opp_table: opp-table {
+				compatible = "operating-points-v2-adreno",
+					     "operating-points-v2";
+
+				opp-310000000 {
+					opp-hz = /bits/ 64 <310000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+					opp-peak-kBps = <2136719>;
+					opp-supported-hw = <0xf>;
+					/* ACD is disabled */
+				};
+
+				opp-410000000 {
+					opp-hz = /bits/ 64 <410000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+					opp-peak-kBps = <6074219>;
+					opp-supported-hw = <0xf>;
+					/* ACD is disabled */
+				};
+
+				opp-572000000 {
+					opp-hz = /bits/ 64 <572000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+					opp-peak-kBps = <12449219>;
+					opp-supported-hw = <0xf>;
+					qcom,opp-acd-level = <0xe02d5ffd>;
+				};
+
+				opp-760000000 {
+					opp-hz = /bits/ 64 <760000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+					opp-peak-kBps = <12449219>;
+					opp-supported-hw = <0xf>;
+					qcom,opp-acd-level = <0xc0285ffd>;
+				};
+
+				opp-820000000 {
+					opp-hz = /bits/ 64 <820000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+					opp-peak-kBps = <16500000>;
+					opp-supported-hw = <0xf>;
+					qcom,opp-acd-level = <0xa82e5ffd>;
+				};
+
+				opp-915000000 {
+					opp-hz = /bits/ 64 <915000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+					opp-peak-kBps = <16500000>;
+					opp-supported-hw = <0xf>;
+					qcom,opp-acd-level = <0x882d5ffd>;
+				};
+
+				opp-1070000000 {
+					opp-hz = /bits/ 64 <1070000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+					opp-peak-kBps = <16500000>;
+					opp-supported-hw = <0xf>;
+					qcom,opp-acd-level = <0x882b5ffd>;
+				};
+
+				opp-1185000000 {
+					opp-hz = /bits/ 64 <1185000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+					opp-peak-kBps = <16500000>;
+					opp-supported-hw = <0xf>;
+					qcom,opp-acd-level = <0x882a5ffd>;
+				};
+
+				opp-1350000000 {
+					opp-hz = /bits/ 64 <1350000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+					opp-peak-kBps = <18597657>;
+					opp-supported-hw = <0xf>;
+					qcom,opp-acd-level = <0x882a5ffd>;
+				};
+
+				opp-1550000000 {
+					opp-hz = /bits/ 64 <1550000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3>;
+					opp-peak-kBps = <18597657>;
+					opp-supported-hw = <0x7>;
+					qcom,opp-acd-level = <0xa8295ffd>;
+				};
+
+				opp-1700000000 {
+					opp-hz = /bits/ 64 <1700000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L4>;
+					opp-peak-kBps = <18597657>;
+					opp-supported-hw = <0x7>;
+					qcom,opp-acd-level = <0x88295ffd>;
+				};
+
+				opp-1850000000 {
+					opp-hz = /bits/ 64 <1850000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L5>;
+					opp-peak-kBps = <18597657>;
+					opp-supported-hw = <0x3>;
+					qcom,opp-acd-level = <0x88285ffd>;
+				};
+			};
+		};
+
 		gxclkctl: clock-controller@3d64000 {
 			compatible = "qcom,glymur-gxclkctl";
 			reg = <0x0 0x03d64000 0x0 0x6000>;
@@ -3712,6 +3835,66 @@ gxclkctl: clock-controller@3d64000 {
 			#power-domain-cells = <1>;
 		};
 
+		gmu: gmu@3d6c000 {
+			compatible = "qcom,adreno-gmu-x285.1", "qcom,adreno-gmu";
+
+			reg = <0x0 0x03d6c000 0x0 0x32000>;
+			reg-names = "gmu";
+
+			interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "hfi",
+					  "gmu";
+
+			clocks = <&gpucc GPU_CC_AHB_CLK>,
+				 <&gpucc GPU_CC_CX_GMU_CLK>,
+				 <&gpucc GPU_CC_CXO_CLK>,
+				 <&gcc GCC_GPU_GEMNOC_GFX_CLK>,
+				 <&gpucc GPU_CC_HUB_CX_INT_CLK>,
+				 <&gpucc GPU_CC_RSCC_HUB_AON_CLK>;
+			clock-names = "ahb",
+				      "gmu",
+				      "cxo",
+				      "memnoc",
+				      "hub",
+				      "rscc";
+
+			power-domains = <&gpucc GPU_CC_CX_GDSC>,
+					<&gxclkctl GX_CLKCTL_GX_GDSC>;
+			power-domain-names = "cx",
+					     "gx";
+
+			iommus = <&adreno_smmu 5 0x0>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			operating-points-v2 = <&gmu_opp_table>;
+
+			gmu_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-575000000 {
+					opp-hz = /bits/ 64 <575000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+				};
+
+				opp-700000000 {
+					opp-hz = /bits/ 64 <700000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+				};
+
+				opp-725000000 {
+					opp-hz = /bits/ 64 <725000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+				};
+
+				opp-750000000 {
+					opp-hz = /bits/ 64 <750000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+				};
+			};
+		};
+
 		gpucc: clock-controller@3d90000 {
 			compatible = "qcom,glymur-gpucc";
 			reg = <0x0 0x03d90000 0x0 0x9800>;

-- 
2.51.0



^ permalink raw reply related

* [PATCH v4 4/6] arm64: dts: qcom: glymur: Add GPU smmu node
From: Akhil P Oommen @ 2026-05-12 19:21 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Rob Clark, Sean Paul, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Will Deacon, Robin Murphy, Joerg Roedel
  Cc: linux-arm-msm, devicetree, linux-kernel, dri-devel, freedreno,
	linux-arm-kernel, iommu, Akhil P Oommen, Rajendra Nayak,
	Konrad Dybcio, Dmitry Baryshkov
In-Reply-To: <20260513-glymur-gpu-dt-v4-0-f83832c3bc9a@oss.qualcomm.com>

From: Rajendra Nayak <rajendra.nayak@oss.qualcomm.com>

Add the nodes to describe the GPU SMMU node.

Signed-off-by: Rajendra Nayak <rajendra.nayak@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/glymur.dtsi | 38 ++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi
index ed9aac42fcbf..5e76a0d53f01 100644
--- a/arch/arm64/boot/dts/qcom/glymur.dtsi
+++ b/arch/arm64/boot/dts/qcom/glymur.dtsi
@@ -3729,6 +3729,44 @@ gpucc: clock-controller@3d90000 {
 			#power-domain-cells = <1>;
 		};
 
+		adreno_smmu: iommu@3da0000 {
+			compatible = "qcom,glymur-smmu-500", "qcom,adreno-smmu",
+				     "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x03da0000 0x0 0x40000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <1>;
+			interrupts = <GIC_SPI 674 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 688 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 574 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 575 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 660 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 662 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 667 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 670 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 700 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gpucc GPU_CC_GPU_SMMU_VOTE_CLK>;
+			clock-names = "hlos";
+			power-domains = <&gpucc GPU_CC_CX_GDSC>;
+			dma-coherent;
+		};
+
 		ipcc: mailbox@3e04000 {
 			compatible = "qcom,glymur-ipcc", "qcom,ipcc";
 			reg = <0x0 0x03e04000 0x0 0x1000>;

-- 
2.51.0



^ permalink raw reply related

* [PATCH v4 3/6] dt-bindings: arm-smmu: Update the description for Glymur GPU SMMU
From: Akhil P Oommen @ 2026-05-12 19:21 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Rob Clark, Sean Paul, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Will Deacon, Robin Murphy, Joerg Roedel
  Cc: linux-arm-msm, devicetree, linux-kernel, dri-devel, freedreno,
	linux-arm-kernel, iommu, Akhil P Oommen
In-Reply-To: <20260513-glymur-gpu-dt-v4-0-f83832c3bc9a@oss.qualcomm.com>

Add the interconnects property to the common SMMU properties and extend
the sm8750 clock description section to also cover Glymur since it uses
the same single "hlos" vote clock.

Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index 06fb5c8e7547..b811ece722c9 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -566,7 +566,9 @@ allOf:
       properties:
         compatible:
           items:
-            - const: qcom,sm8750-smmu-500
+            - enum:
+                - qcom,glymur-smmu-500
+                - qcom,sm8750-smmu-500
             - const: qcom,adreno-smmu
             - const: qcom,smmu-500
             - const: arm,mmu-500

-- 
2.51.0



^ permalink raw reply related

* [PATCH v4 2/6] dt-bindings: display/msm: gpu: Document Adreno X2-185
From: Akhil P Oommen @ 2026-05-12 19:21 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Rob Clark, Sean Paul, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Will Deacon, Robin Murphy, Joerg Roedel
  Cc: linux-arm-msm, devicetree, linux-kernel, dri-devel, freedreno,
	linux-arm-kernel, iommu, Akhil P Oommen
In-Reply-To: <20260513-glymur-gpu-dt-v4-0-f83832c3bc9a@oss.qualcomm.com>

Adreno X2-185 GPU found in Glymur chipsets belongs to the A8x family.
It features a new slice architecture with 4 slices, significantly higher
bandwidth throughput compared to mobile counterparts, raytracing support,
and the highest GPU Fmax seen so far on an Adreno GPU (1850 Mhz), among
other improvements. Update the dt bindings documentation to describe this
GPU.

Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
 Documentation/devicetree/bindings/display/msm/gpu.yaml | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml b/Documentation/devicetree/bindings/display/msm/gpu.yaml
index 04b2328903ca..e67cd708dda2 100644
--- a/Documentation/devicetree/bindings/display/msm/gpu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml
@@ -411,6 +411,22 @@ allOf:
         - clocks
         - clock-names
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: qcom,adreno-44070001
+    then:
+      properties:
+        reg:
+          minItems: 2
+          maxItems: 2
+
+        reg-names:
+          items:
+            - const: kgsl_3d0_reg_memory
+            - const: cx_mem
+
   - if:
       properties:
         compatible:
@@ -434,6 +450,7 @@ allOf:
               - qcom,adreno-43050a01
               - qcom,adreno-43050c01
               - qcom,adreno-43051401
+              - qcom,adreno-44070001
 
     then: # Starting with A6xx, the clocks are usually defined in the GMU node
       properties:

-- 
2.51.0



^ permalink raw reply related

* [PATCH v4 1/6] drm/msm/a8xx: Fix RSCC offset
From: Akhil P Oommen @ 2026-05-12 19:21 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Rob Clark, Sean Paul, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Will Deacon, Robin Murphy, Joerg Roedel
  Cc: linux-arm-msm, devicetree, linux-kernel, dri-devel, freedreno,
	linux-arm-kernel, iommu, Akhil P Oommen
In-Reply-To: <20260513-glymur-gpu-dt-v4-0-f83832c3bc9a@oss.qualcomm.com>

In A8xx, the RSCC block is part of GPU's register space. Update the
virtual base address of rscc to point to the correct address.

Fixes: 50e8a557d8d3 ("drm/msm/a8xx: Add support for A8x GMU")
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 1b44b9e21ad8..cab4c46c6cf2 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -2357,7 +2357,12 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
 			goto err_mmio;
 		}
 	} else if (adreno_is_a8xx(adreno_gpu)) {
-		gmu->rscc = gmu->mmio + 0x19000;
+		/*
+		 * On a8xx , RSCC lives at GPU base + 0x50000, which falls
+		 * inside the GPU's kgsl_3d0_reg_memory range rather than the
+		 * GMU's.
+		 */
+		gmu->rscc = gpu->mmio + 0x50000;
 	} else {
 		gmu->rscc = gmu->mmio + 0x23000;
 	}

-- 
2.51.0



^ permalink raw reply related

* [PATCH v4 0/6] Devicetree support for Glymur GPU
From: Akhil P Oommen @ 2026-05-12 19:21 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Rob Clark, Sean Paul, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Will Deacon, Robin Murphy, Joerg Roedel
  Cc: linux-arm-msm, devicetree, linux-kernel, dri-devel, freedreno,
	linux-arm-kernel, iommu, Akhil P Oommen, Rajendra Nayak,
	Konrad Dybcio, Dmitry Baryshkov, Manaf Meethalavalappu Pallikunhi

This series adds the necessary Device Tree bits to enable GPU support
on the Glymur-based CRD devices. The Adreno X2-85 GPU present in Glymur
chipsets is based on the new Adreno A8x family of GPUs. It features a new
slice architecture with 4 slices, significantly higher bandwidth
throughput compared to mobile counterparts, raytracing support, and the
highest GPU Fmax seen so far on an Adreno GPU (1850 Mhz), among other
improvements.

This series includes patches that updates DT schema, add GPU SMMU &
GPU/GMU support. Keen-eyed readers may notice that the zap shader node
is missing. This is intentional: The Glymur-based laptop platforms
generally allow booting Linux at EL2 (yay!), which means the zap firmware
is not required here.

There is an update to the gxclkctl/drm drivers to properly support the IFPC
feature across all A8x GPUs. That series [1] is necessary to properly
support Glymur GPU:
[1] https://lore.kernel.org/lkml/20260427-gfx-clk-fixes-v2-0-797e54b3d464@oss.qualcomm.com/

Just FYI, on top of the linux-next, I had to pick below series [2] to boot
the device properly. But it is unrelated to GPU or this series:
[2] https://lore.kernel.org/all/20260331-qref_vote-v1-0-3fd7fbf87864@oss.qualcomm.com/

Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
Changes in v4:
- Add a new patch for passive cooling support
- Link to v3: https://lore.kernel.org/r/20260512-glymur-gpu-dt-v3-0-84232dc21c03@oss.qualcomm.com

Changes in v3:
- Add a new patch to fix RSCC base vaddr in drm-msm
- Remove interconnect property from adreno smmu dt and the binding doc
- Add a contrait in GPU binding doc to limit the reg entries for Glymur
  (Krzysztof)
- Link to v2: https://lore.kernel.org/r/20260501-glymur-gpu-dt-v2-0-2f128b5596bb@oss.qualcomm.com

Changes in v2:
- Keep GPU/GMU enabled by default and drop the enablement patch (Konrad)
- Drop zap shader node from DT
- A new patch to update GPU SMMU dt schema.
- Adjust reg range in dt nodes to avoid overlap. 
- Removed cx_dbgc range as it is already stable across chipsets. This
  region is now part of kgsl_3d0_reg_memory range.
- Link to v1: https://lore.kernel.org/r/20260405-glymur-gpu-dt-v1-0-2135eb11c562@oss.qualcomm.com

---
Akhil P Oommen (4):
      drm/msm/a8xx: Fix RSCC offset
      dt-bindings: display/msm: gpu: Document Adreno X2-185
      dt-bindings: arm-smmu: Update the description for Glymur GPU SMMU
      arm64: dts: qcom: Add GPU support for Glymur

Manaf Meethalavalappu Pallikunhi (1):
      arm64: dts: qcom: glymur: Add GPU cooling

Rajendra Nayak (1):
      arm64: dts: qcom: glymur: Add GPU smmu node

 .../devicetree/bindings/display/msm/gpu.yaml       |  17 +
 .../devicetree/bindings/iommu/arm,smmu.yaml        |   4 +-
 arch/arm64/boot/dts/qcom/glymur.dtsi               | 461 ++++++++++++++++++---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c              |   7 +-
 4 files changed, 431 insertions(+), 58 deletions(-)
---
base-commit: c9bd03db3e792a99e9789fde20e91898e3a29e8a
change-id: 20260226-glymur-gpu-dt-339e5092606b
prerequisite-message-id: <20260410-glymur_mmcc_dt_config_v2-v3-0-acce9d106e72@oss.qualcomm.com>
prerequisite-patch-id: f7ab29f2f0241b6536d3b0c0593f0baa0e435221
prerequisite-patch-id: 56c830b7718129323b006e492aed9822d7c30079

Best regards,
-- 
Akhil P Oommen <akhilpo@oss.qualcomm.com>



^ permalink raw reply

* Re: [PATCH] ARM: OMAP2+: Make OMAP4 finish_suspend callback CFI-safe
From: Andreas Kemnade @ 2026-05-12 19:05 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Mithil Bavishi, Aaro Koskinen, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Russell King, Sami Tolvanen, Kees Cook,
	linux-arm-kernel, linux-omap, llvm, linux-kernel
In-Reply-To: <20260512135757.GB570003@ax162>

On Tue, 12 May 2026 22:57:57 +0900
Nathan Chancellor <nathan@kernel.org> wrote:

> On Tue, May 12, 2026 at 10:02:07AM +0200, Andreas Kemnade wrote:
> > On Tue, 12 May 2026 16:34:42 +0900
> > Nathan Chancellor <nathan@kernel.org> wrote:
> >   
> > > On Tue, May 12, 2026 at 12:23:41AM -0400, Mithil Bavishi wrote:  
> > > > With CONFIG_CFI enabled, OMAP4 can trap in omap4_enter_lowpower()
> > > > because omap_pm_ops.finish_suspend points directly to the assembly
> > > > routine omap4_finish_suspend, which lacks the expected KCFI type
> > > > metadata.    
> > > 
> > > It sounds like omap4_finish_suspend() should be defined with
> > > SYM_TYPED_FUNC_START then? Is that the case for all of the other
> > > functions that are added to omap_pm_ops?
> > >   
> > omap_cpu_resume: the address is written to some cpu register and
> > on that way casted to u32. So therefore does not trigger CFI.
> > Same for secondary_startup which is also assembler code.
> > scu_prepare is C.
> > 
> > DO you have a pointer to any documentation:
> > :~/linux$ grep -R SYM_TYPED_FUNC_START Documentation/  
> 
> I don't think we have any formal documentation for SYM_TYPED_FUNC_START
> (it should probably be documented via kernel-doc?) but you can read the
> commit message of the change that added it for more information:
> 
>   e84e008e7b02 ("cfi: Add type helper macros")
> 
Ok, I found what is the missing piece of the puzzle in my head:
"
In order to make this easier, the compiler emits a
    __kcfi_typeid_<function> symbol for each address-taken function
    declaration in C, which contains the expected type identifier that
    we can refer to in assembly code.
"
So time to look into my backyard if anything more is there.

Regards,
Andreas


^ permalink raw reply

* Re: [PATCH v3 6/7] gpio: realtek: Add driver for Realtek DHC RTD1625 SoC
From: Andy Shevchenko @ 2026-05-12 18:50 UTC (permalink / raw)
  To: Yu-Chun Lin
  Cc: linusw, brgl, robh, krzk+dt, conor+dt, afaerber, wbg,
	mathieu.dubois-briand, mwalle, lars, Michael.Hennerich, jic23,
	nuno.sa, andy, dlechner, tychang, linux-gpio, devicetree,
	linux-kernel, linux-arm-kernel, linux-realtek-soc, linux-iio,
	cy.huang, stanley_chang, james.tai
In-Reply-To: <20260512033317.1602537-7-eleanor.lin@realtek.com>

On Tue, May 12, 2026 at 11:33:16AM +0800, Yu-Chun Lin wrote:

> Add support for the GPIO controller found on Realtek DHC RTD1625 SoCs.

The below paragraphs are all the implementation details that are not so
important to be in the commit message. They fit the comment block after
the '---' line below, though...

> Unlike the existing Realtek GPIO driver (drivers/gpio/gpio-rtd.c),
> which manages pins via shared bank registers, the RTD1625 introduces
> a per-pin register architecture. Each GPIO line now has its own
> dedicated 32-bit control register to manage configuration independently,
> including direction, output value, input value, interrupt enable, and
> debounce. Therefore, this distinct hardware design requires a separate
> driver.
> 
> The driver leverages the gpio-regmap framework, utilizing the recently
> introduced write-enable and operation-specific mask translation features.
> 
> Additionally, because the controller utilizes multiple independent IRQ
> status registers (assert, de-assert, and level) which cannot be mapped
> via standard regmap_irq_chip, the driver implements a custom irq_domain.
> 
> Signed-off-by: Tzuyi Chang <tychang@realtek.com>
> Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
> Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
> ---

...somewhere here.

...


> +#include <linux/bitfield.h>
> +#include <linux/bitops.h>

Missing cleanup.h, may be more.

> +#include <linux/gpio/driver.h>
> +#include <linux/gpio/regmap.h>
> +#include <linux/interrupt.h>
> +#include <linux/irqchip.h>

> +#include <linux/irqdomain.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/irqdomain.h>

If you sort headers alphabetically, you will see the duplication.

> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/regmap.h>
> +#include <linux/spinlock.h>
> +#include <linux/types.h>

...

> +struct rtd1625_gpio {
> +	struct gpio_chip *gpio_chip;
> +	const struct rtd1625_gpio_info *info;

> +	void __iomem *base;

Is it used? Also naming is confusing with unsigned int base in some functions
below.

> +	struct regmap *regmap;
> +	unsigned int irqs[3];

This 3 is also used when assign num_irqs below, perhaps define it with
meaningful name? (The 2 also might need a definition in the same way.)

> +	raw_spinlock_t lock;
> +	struct irq_domain *domain;
> +	unsigned int *save_regs;
> +};

...

> +static int rtd1625_reg_mask_xlate(struct gpio_regmap *gpio, enum gpio_regmap_operation op,
> +				  unsigned int base, unsigned int offset, unsigned int *reg,
> +				  unsigned int *mask)

Use logical split.

static int rtd1625_reg_mask_xlate(struct gpio_regmap *gpio, enum gpio_regmap_operation op,
				  unsigned int base, unsigned int offset,
				  unsigned int *reg, unsigned int *mask)

OR (as suggested earlier)

static int rtd1625_reg_mask_xlate(struct gpio_regmap *gpio,
				  enum gpio_regmap_operation op,
				  unsigned int base, unsigned int offset,
				  unsigned int *reg, unsigned int *mask)

...

> +static unsigned int rtd1625_gpio_set_debounce(struct gpio_chip *chip, unsigned int offset,
> +					      unsigned int debounce)
> +{
> +	struct rtd1625_gpio *data = gpiochip_get_data(chip);
> +	u8 deb_val;
> +	u32 val;
> +
> +	switch (debounce) {
> +	case 1:
> +		deb_val = RTD1625_GPIO_DEBOUNCE_1US;
> +		break;
> +	case 10:
> +		deb_val = RTD1625_GPIO_DEBOUNCE_10US;
> +		break;
> +	case 100:
> +		deb_val = RTD1625_GPIO_DEBOUNCE_100US;
> +		break;
> +	case 1000:
> +		deb_val = RTD1625_GPIO_DEBOUNCE_1MS;
> +		break;
> +	case 10000:
> +		deb_val = RTD1625_GPIO_DEBOUNCE_10MS;
> +		break;
> +	case 20000:
> +		deb_val = RTD1625_GPIO_DEBOUNCE_20MS;
> +		break;
> +	case 30000:
> +		deb_val = RTD1625_GPIO_DEBOUNCE_30MS;
> +		break;
> +	case 50000:
> +		deb_val = RTD1625_GPIO_DEBOUNCE_50MS;
> +		break;
> +	default:
> +		return -ENOTSUPP;
> +	}
> +
> +	val = FIELD_PREP(RTD1625_GPIO_DEBOUNCE, deb_val) | RTD1625_GPIO_DEBOUNCE_WREN;

> +	regmap_write(data->regmap, GPIO_CONTROL(offset), val);

Neither here, nor in some other places the returned value from regmap APIs is
not checked. Is it okay?

> +	return 0;
> +}
> +
> +static int rtd1625_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
> +				   unsigned long config)
> +{
> +	int debounce;

Can it be negative?

> +	if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE) {
> +		debounce = pinconf_to_config_argument(config);
> +		return rtd1625_gpio_set_debounce(chip, offset, debounce);
> +	}
> +
> +	return gpiochip_generic_config(chip, offset, config);
> +}

...

> +static void rtd1625_gpio_irq_handle(struct irq_desc *desc)
> +{
> +	unsigned int (*get_reg_offset)(struct rtd1625_gpio *gpio, unsigned int offset);
> +	struct rtd1625_gpio *data = irq_desc_get_handler_data(desc);
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	unsigned int irq = irq_desc_get_irq(desc);
> +	struct irq_domain *domain = data->domain;
> +	unsigned int reg_offset, i, j, val;
> +	irq_hw_number_t hwirq;
> +	unsigned long status;
> +	unsigned int girq;
> +	u32 irq_type;
> +
> +	if (irq == data->irqs[0])
> +		get_reg_offset = &rtd1625_gpio_gpa_offset;
> +	else if (irq == data->irqs[1])
> +		get_reg_offset = &rtd1625_gpio_gpda_offset;
> +	else if (irq == data->irqs[2])
> +		get_reg_offset = &rtd1625_gpio_level_offset;
> +	else
> +		return;
> +
> +	chained_irq_enter(chip, desc);

> +	for (i = 0; i < data->info->num_gpios; i += 32) {

	for (unsigned int i = 0; i < data->info->num_gpios; i += 32) {

> +		reg_offset = get_reg_offset(data, i);
> +		regmap_read(data->regmap, reg_offset, &val);
> +
> +		status = val;
> +
> +		/* Clear edge interrupts; level interrupts are cleared in ->irq_ack() */
> +		if (irq != data->irqs[2])
> +			regmap_write(data->regmap, reg_offset, status);

This is interesting... Can't we rely on IRQ core to take care of this? (And
replay if required.)

> +		for_each_set_bit(j, &status, 32) {
> +			hwirq = i + j;
> +			girq = irq_find_mapping(domain, hwirq);
> +			irq_type = irq_get_trigger_type(girq);

> +			if (irq == data->irqs[1] && irq_type != IRQ_TYPE_EDGE_BOTH)

Why is the IRQ type check here and not in set_type() callback?
I think we should simply reject to even lock such a configuration as IRQ.

> +				continue;
> +
> +			generic_handle_domain_irq(domain, hwirq);
> +		}
> +	}
> +
> +	chained_irq_exit(chip, desc);
> +}

> +static void rtd1625_gpio_enable_edge_irq(struct rtd1625_gpio *data, irq_hw_number_t hwirq)
> +{
> +	int gpda_reg_offset = rtd1625_gpio_gpda_offset(data, hwirq);
> +	int gpa_reg_offset = rtd1625_gpio_gpa_offset(data, hwirq);
> +	u32 clr_mask = BIT(hwirq % 32);
> +	u32 val;
> +
> +	guard(raw_spinlock_irqsave)(&data->lock);

+ blank line. Same to other cases when guard()() is being used.

> +	regmap_write(data->regmap, gpa_reg_offset, clr_mask);
> +	regmap_write(data->regmap, gpda_reg_offset, clr_mask);
> +	val = RTD1625_GPIO_EDGE_INT_EN | RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_INT_EN);
> +	regmap_write(data->regmap, data->info->base_offset + GPIO_CONTROL(hwirq), val);
> +}

...

> +static void rtd1625_gpio_enable_irq(struct irq_data *d)
> +{
> +	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> +	u32 irq_type = irqd_get_trigger_type(d);
> +	struct rtd1625_gpio *data;
> +	struct gpio_regmap *gpio;

> +	gpio = gpiochip_get_data(gc);
> +	data = gpio_regmap_get_drvdata(gpio);

Why not unify these with the above, we don't validate them anyway...
Same Q to other cases like this.

> +	gpiochip_enable_irq(gc, hwirq);
> +
> +	if (irq_type & IRQ_TYPE_EDGE_BOTH)
> +		rtd1625_gpio_enable_edge_irq(data, hwirq);
> +	else if (irq_type & IRQ_TYPE_LEVEL_MASK)
> +		rtd1625_gpio_enable_level_irq(data, hwirq);
> +}

...

> +static int rtd1625_gpio_irq_set_level_type(struct irq_data *d, bool level)
> +{
> +	u32 val = RTD1625_GPIO_WREN(RTD1625_GPIO_LEVEL_INT_DP);
> +	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> +	struct rtd1625_gpio *data;
> +	struct gpio_regmap *gpio;
> +
> +	gpio = gpiochip_get_data(gc);
> +	data = gpio_regmap_get_drvdata(gpio);

+ blank line (and actually see above).

> +	if (!(data->info->irq_type_support & IRQ_TYPE_LEVEL_MASK))
> +		return -EINVAL;

> +	scoped_guard(raw_spinlock_irqsave, &data->lock) {

> +		if (level)
> +			val |= RTD1625_GPIO_LEVEL_INT_DP;

Why this local variable change is under the lock?

> +		regmap_write(data->regmap, data->info->base_offset + GPIO_CONTROL(hwirq), val);
> +	}
> +
> +	irq_set_handler_locked(d, handle_level_irq);
> +
> +	return 0;
> +}

...

> +static int rtd1625_gpio_irq_set_edge_type(struct irq_data *d, bool polarity)

Similar comments as per above.

...

> +static int rtd1625_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> +{
> +	int ret;

Unneeded, just return directly from each of the cases.

> +
> +	switch (type & IRQ_TYPE_SENSE_MASK) {
> +	case IRQ_TYPE_EDGE_RISING:
> +		ret = rtd1625_gpio_irq_set_edge_type(d, 1);
> +		break;
> +	case IRQ_TYPE_EDGE_FALLING:
> +		ret = rtd1625_gpio_irq_set_edge_type(d, 0);
> +		break;
> +	case IRQ_TYPE_EDGE_BOTH:
> +		ret = rtd1625_gpio_irq_set_edge_type(d, 1);
> +		break;
> +	case IRQ_TYPE_LEVEL_HIGH:
> +		ret = rtd1625_gpio_irq_set_level_type(d, 0);
> +		break;
> +	case IRQ_TYPE_LEVEL_LOW:
> +		ret = rtd1625_gpio_irq_set_level_type(d, 1);
> +		break;
> +	default:
> +		ret = -EINVAL;

Missing break, but rather simply

		return -EINVAL;

as mentioned above. In the similar way for the rest of switch-cases.

> +	}
> +
> +	return ret;
> +}

...

> +static int rtd1625_gpio_setup_irq(struct platform_device *pdev, struct rtd1625_gpio *data)
> +{
> +	int num_irqs, irq, i;

Why is 'num_irqs' signed?

> +	irq = platform_get_irq_optional(pdev, 0);
> +	if (irq == -ENXIO)
> +		return 0;

This is strange. You mean that you are only interested in the first IRQ? What
about the case when the first one is not available, while the second is?

> +	if (irq < 0)
> +		return irq;

This partially duplicates the below.

> +	num_irqs = (data->info->irq_type_support & IRQ_TYPE_LEVEL_MASK) ? 3 : 2;

> +	for (i = 0; i < num_irqs; i++) {

The iterator is local to the loop, hence

	for (unsigned int i = 0; i < num_irqs; i++) {

> +		irq = platform_get_irq(pdev, i);
> +		if (irq < 0)
> +			return irq;
> +
> +		data->irqs[i] = irq;
> +		irq_set_chained_handler_and_data(data->irqs[i], rtd1625_gpio_irq_handle, data);
> +	}
> +
> +	return 0;
> +}

...

> +static int rtd1625_gpio_irq_map(struct irq_domain *domain, unsigned int irq,
> +				irq_hw_number_t hwirq)
> +{
> +	struct rtd1625_gpio *data = domain->host_data;
> +
> +	irq_set_chip_data(irq, data->gpio_chip);
> +
> +	irq_set_chip_and_handler(irq, &rtd1625_iso_gpio_irq_chip, handle_bad_irq);
> +
> +	irq_set_noprobe(irq);

Shouldn't you assign a lockdep class?

> +	return 0;
> +}

...

> +static const struct regmap_config rtd1625_gpio_regmap_config = {
> +	.reg_bits = 32,
> +	.reg_stride = 4,
> +	.val_bits = 32,

> +	.disable_locking = true,

Hmm... This effectively drops the debugfs support, perhaps make it depend on
CONFIG_DEBUG_GPIO?

> +};

...

> +static int rtd1625_gpio_probe(struct platform_device *pdev)
> +{
> +	struct gpio_regmap_config config = {0};

'0' is redundant.

> +	struct device *dev = &pdev->dev;
> +	struct gpio_regmap *gpio_reg;
> +	struct rtd1625_gpio *data;
> +	void __iomem *irq_base;
> +	int ret;
> +
> +	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> +	if (!data)
> +		return -ENOMEM;
> +
> +	data->info = device_get_match_data(dev);
> +	if (!data->info)
> +		return -EINVAL;
> +
> +	irq_base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(irq_base))
> +		return PTR_ERR(irq_base);
> +
> +	data->regmap = devm_regmap_init_mmio(dev, irq_base,
> +					     &rtd1625_gpio_regmap_config);

I would go with a single line

	data->regmap = devm_regmap_init_mmio(dev, irq_base, &rtd1625_gpio_regmap_config);

> +	if (IS_ERR(data->regmap))
> +		return PTR_ERR(data->regmap);
> +
> +	data->save_regs = devm_kzalloc(dev, data->info->num_gpios *
> +				       sizeof(*data->save_regs), GFP_KERNEL);

This is devm_kcalloc().

> +	if (!data->save_regs)
> +		return -ENOMEM;
> +
> +	config.parent = dev;
> +	config.regmap = data->regmap;
> +	config.ngpio = data->info->num_gpios;
> +	config.reg_dat_base = data->info->base_offset;
> +	config.reg_set_base = data->info->base_offset;
> +	config.reg_mask_xlate = rtd1625_reg_mask_xlate;
> +	config.set_config = rtd1625_gpio_set_config;
> +	config.reg_dir_out_base = data->info->base_offset;
> +
> +	data->domain = irq_domain_add_linear(dev->of_node,

No, use fwnode variant from the start.

> +					     data->info->num_gpios,
> +					     &rtd1625_gpio_irq_domain_ops,
> +					     data);
> +	if (!data->domain)
> +		return -ENOMEM;
> +
> +	ret = rtd1625_gpio_setup_irq(pdev, data);
> +	if (ret) {
> +		irq_domain_remove(data->domain);
> +		return ret;
> +	}
> +
> +	config.irq_domain = data->domain;
> +	config.drvdata = data;
> +	platform_set_drvdata(pdev, data);
> +
> +	gpio_reg = devm_gpio_regmap_register(dev, &config);
> +	if (IS_ERR(gpio_reg)) {

> +		irq_domain_remove(data->domain);

This is wrong. The remove will do the opposite order. It means that
irq_domain_create_linear() has to be wrapped to become a managed resource.

> +		return PTR_ERR(gpio_reg);
> +	}
> +
> +	data->gpio_chip = gpio_regmap_get_gpiochip(gpio_reg);
> +
> +	return 0;
> +}
> +
> +static const struct rtd1625_gpio_info rtd1625_iso_gpio_info = {
> +	.num_gpios		= 166,
> +	.irq_type_support	= IRQ_TYPE_EDGE_BOTH,
> +	.base_offset		= 0x100,
> +	.gpa_offset		= 0x0,
> +	.gpda_offset		= 0x20,

Use fixed-width for the register offsets, id est 0x000, 0x020, and so on...

> +	.write_en_all		= RTD1625_ISO_GPIO_WREN_ALL,
> +};
> +
> +static const struct rtd1625_gpio_info rtd1625_isom_gpio_info = {
> +	.num_gpios		= 4,
> +	.irq_type_support	= IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_LOW |
> +				  IRQ_TYPE_LEVEL_HIGH,
> +	.base_offset		= 0x20,
> +	.gpa_offset		= 0x0,
> +	.gpda_offset		= 0x4,
> +	.level_offset		= 0x18,
> +	.write_en_all		= RTD1625_ISOM_GPIO_WREN_ALL,
> +};

...

> +static const struct of_device_id rtd1625_gpio_of_matches[] = {
> +	{ .compatible = "realtek,rtd1625-iso-gpio", .data = &rtd1625_iso_gpio_info },
> +	{ .compatible = "realtek,rtd1625-isom-gpio", .data = &rtd1625_isom_gpio_info },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, rtd1625_gpio_of_matches);

Move the initialiser and respective MODULE_DEVICE_TABLE() closer to its user.

...

> +static int rtd1625_gpio_suspend(struct device *dev)
> +{
> +	struct rtd1625_gpio *data = dev_get_drvdata(dev);
> +	const struct rtd1625_gpio_info *info = data->info;
> +	int i;
> +
> +	for (i = 0; i < info->num_gpios; i++)

	for (unsigned int i = 0; i < info->num_gpios; i++)

> +		regmap_read(data->regmap, data->info->base_offset + GPIO_CONTROL(i),
> +			    &data->save_regs[i]);
> +
> +	return 0;
> +}
> +
> +static int rtd1625_gpio_resume(struct device *dev)
> +{
> +	struct rtd1625_gpio *data = dev_get_drvdata(dev);
> +	const struct rtd1625_gpio_info *info = data->info;
> +	int i;
> +
> +	for (i = 0; i < info->num_gpios; i++)

Ditto.

> +		regmap_write(data->regmap, data->info->base_offset + GPIO_CONTROL(i),
> +			     data->save_regs[i] | info->write_en_all);
> +
> +	return 0;
> +}

...

> +DEFINE_NOIRQ_DEV_PM_OPS(rtd1625_gpio_pm_ops, rtd1625_gpio_suspend, rtd1625_gpio_resume);

Not static? Why?

-- 
With Best Regards,
Andy Shevchenko




^ permalink raw reply

* Re: [PATCH 2/2] ARM: dts: aspeed: Add ASRock Rack B650D4U BMC
From: Andrew Lunn @ 2026-05-12 18:35 UTC (permalink / raw)
  To: Prasanth Kumar Padarthi
  Cc: joel, andrew, robh, krzk+dt, conor+dt, devicetree, linux-aspeed,
	linux-arm-kernel
In-Reply-To: <20260512175019.47548-3-prasanth.padarthi10@gmail.com>

> +/* Dedicated Management LAN */
> +&mac0 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;

What does this connect to? A PHY? NCSI?

     Andrew


^ permalink raw reply

* Re: [PATCH 1/1] dt-bindings: display: imx: add deprecated property 'port' and 'display-timings'
From: Frank Li @ 2026-05-12 18:21 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Philipp Zabel, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam,
	open list:DRM DRIVERS FOR FREESCALE IMX 5/6,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	open list
In-Reply-To: <20260512-surgery-operative-046a90f84ef8@spud>

On Tue, May 12, 2026 at 05:47:11PM +0100, Conor Dooley wrote:
> On Mon, May 11, 2026 at 06:09:24PM -0400, Frank Li wrote:
> > Add deprecated property 'port' and 'display-timings' for i.MX5 SoCs (over
> > 15 years) to fix below CHECK_DTBS warnings:
> >   arm/boot/dts/nxp/imx/imx51-apf51dev.dtb: disp1 (fsl,imx-parallel-display): 'display-timings', 'port' do not match any of the regexes: '^pinctrl-[0-9]+$'
> >         from schema $id: http://devicetree.org/schemas/display/imx/fsl,imx-parallel-display.yaml
>
> Instead of documenting the deprecated properties, could this
> device/devicetree be converted to non-deprecated properties?

Change dts will cause break back compatiblity. This is too old chips and
I have not information panel's detail information.

Frank

>
> >
> > Signed-off-by: Frank Li <Frank.Li@nxp.com>
> > ---
> >  .../display/imx/fsl,imx-parallel-display.yaml         | 11 +++++++++++
> >  1 file changed, 11 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx-parallel-display.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx-parallel-display.yaml
> > index bbcfe7e2958b7..b0c5869771fae 100644
> > --- a/Documentation/devicetree/bindings/display/imx/fsl,imx-parallel-display.yaml
> > +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx-parallel-display.yaml
> > @@ -42,6 +42,17 @@ properties:
> >      unevaluatedProperties: false
> >      description: output port connected to a panel
> >
> > +  port:
> > +    $ref: /schemas/graph.yaml#/properties/port
> > +    unevaluatedProperties: false
> > +    deprecated: true
> > +    description: input port connected to the IPU display interface, see port@0
> > +
> > +  display-timings:
> > +    $ref: /schemas/display/panel/display-timings.yaml#
> > +    unevaluatedProperties: false
> > +    deprecated: true
> > +
> >  required:
> >    - compatible
> >
> > --
> > 2.43.0
> >




^ permalink raw reply

* Re: [PATCH v3 4/7] gpio: regmap: Add set_config callback
From: Andy Shevchenko @ 2026-05-12 18:12 UTC (permalink / raw)
  To: Yu-Chun Lin
  Cc: linusw, brgl, robh, krzk+dt, conor+dt, afaerber, wbg,
	mathieu.dubois-briand, mwalle, lars, Michael.Hennerich, jic23,
	nuno.sa, andy, dlechner, tychang, linux-gpio, devicetree,
	linux-kernel, linux-arm-kernel, linux-realtek-soc, linux-iio,
	cy.huang, stanley_chang, james.tai
In-Reply-To: <20260512033317.1602537-5-eleanor.lin@realtek.com>

On Tue, May 12, 2026 at 11:33:14AM +0800, Yu-Chun Lin wrote:
> Add a new set_config callback to struct gpio_regmap_config to allow drivers
> to implement hardware-specific configuration such as debounce settings,
> or other platform-specific GPIO properties.

Okay, if it's needed...
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>

-- 
With Best Regards,
Andy Shevchenko




^ permalink raw reply

* Re: [PATCH v3 1/3] iio: adc: xilinx-ams: fix out-of-bounds channel lookup in event handling
From: Salih Erim @ 2026-05-12 18:05 UTC (permalink / raw)
  To: Jonathan Cameron, Guilherme Ivo Bozi
  Cc: Conall O'Griofa, Michal Simek, David Lechner, Nuno Sá,
	Andy Shevchenko, linux-iio, linux-arm-kernel, linux-kernel
In-Reply-To: <20260512165444.4ae39d90@jic23-huawei>

Hi Jonathan,
>> I could not observe any indentation issues locally or from the raw mbox.
> FWIW they look good to me as well. Salih, I'd guess you have a local issue.
> b4 (on git.kernel.org) is really handy for ensuring none of those occur!

You are right, apologies for the noise. The tabs were converted to
spaces by my email client during export. I will use b4 for patch
retrieval going forward.

There is still the u32 dead code issue in patch 3/3
(event < 0 check on a u32 parameter in ams_event_to_channel()),
Guilherme has acknowledged.

I am currently testing the series on ZCU102 hardware. Will follow up
with my Reviewed-by and Tested-by tags on the v4.

Salih

> 
> Jonathan
> 
>>
>>>
>>> Salih
>>>
>>
>> --
>> Guilherme Ivo
> 



^ permalink raw reply

* [PATCH 2/2] ARM: dts: aspeed: Add ASRock Rack B650D4U BMC
From: Prasanth Kumar Padarthi @ 2026-05-12 17:50 UTC (permalink / raw)
  To: joel, andrew
  Cc: robh, krzk+dt, conor+dt, devicetree, linux-aspeed,
	linux-arm-kernel, Prasanth Kumar Padarthi
In-Reply-To: <20260512175019.47548-1-prasanth.padarthi10@gmail.com>

Add initial device tree support for the ASRock Rack B650D4U BMC.
The B650D4U is a server motherboard utilizing the ASPEED AST2600
SoC for management.

Signed-off-by: Prasanth Kumar Padarthi <prasanth.padarthi10@gmail.com>
---
 arch/arm/boot/dts/aspeed/Makefile             |  1 +
 .../dts/aspeed/aspeed-bmc-asrock-b650d4u.dts  | 61 +++++++++++++++++++
 2 files changed, 62 insertions(+)
 create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-b650d4u.dts

diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
index c4f064e4b..124d4f8f8 100644
--- a/arch/arm/boot/dts/aspeed/Makefile
+++ b/arch/arm/boot/dts/aspeed/Makefile
@@ -13,6 +13,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
 	aspeed-bmc-asrock-romed8hm3.dtb \
 	aspeed-bmc-asrock-spc621d8hm3.dtb \
 	aspeed-bmc-asrock-x570d4u.dtb \
+	aspeed-bmc-asrock-b650d4u.dtb \
 	aspeed-bmc-asus-x4tf.dtb \
 	aspeed-bmc-bytedance-g220a.dtb \
 	aspeed-bmc-delta-ahe50dc.dtb \
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-b650d4u.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-b650d4u.dts
new file mode 100644
index 000000000..d0b9c1e1f
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-b650d4u.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h> // Recommended for GPIO mapping
+
+/ {
+	model = "ASRock Rack B650D4U BMC";
+	compatible = "asrock,b650d4u-bmc", "aspeed,ast2600";
+
+	aliases {
+		serial4 = &uart5;
+	};
+
+	chosen {
+		stdout-path = "serial4:115200n8";
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x40000000>;
+	};
+};
+
+/* BMC Console UART */
+&uart5 {
+	status = "okay";
+};
+
+/* SPI Flash Management */
+&fmc {
+	status = "okay";
+	flash@0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "bmc";
+	};
+};
+
+/* Dedicated Management LAN */
+&mac0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;
+};
+
+/* I2C Bus for FRU/EEPROM Storage */
+&i2c7 {
+	status = "okay";
+	eeprom@57 {
+		compatible = "atmel,24c02";
+		reg = <0x57>;
+		pagesize = <16>;
+	};
+};
+
+/* System Watchdog */
+&wdt1 {
+	status = "okay";
+	aspeed,reset-type = "soc";
+};
-- 
2.47.3



^ permalink raw reply related

* [PATCH 1/2] dt-bindings: arm: aspeed: Add ASRock Rack B650D4U
From: Prasanth Kumar Padarthi @ 2026-05-12 17:50 UTC (permalink / raw)
  To: joel, andrew
  Cc: robh, krzk+dt, conor+dt, devicetree, linux-aspeed,
	linux-arm-kernel, Prasanth Kumar Padarthi
In-Reply-To: <20260512175019.47548-1-prasanth.padarthi10@gmail.com>

Add the compatible string for the ASRock Rack B650D4U BMC,
which is an AST2600-based server motherboard.

Signed-off-by: Prasanth Kumar Padarthi <prasanth.padarthi10@gmail.com>
---
 Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
index 2f92b8ab0..656397850 100644
--- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
+++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
@@ -77,6 +77,7 @@ properties:
               - ampere,mtmitchell-bmc
               - aspeed,ast2600-evb
               - aspeed,ast2600-evb-a1
+              - asrock,b650d4u-bmc
               - asus,x4tf-bmc
               - facebook,bletchley-bmc
               - facebook,catalina-bmc
-- 
2.47.3



^ permalink raw reply related

* [PATCH 0/2] ARM: dts: aspeed: Add ASRock Rack B650D4U support
From: Prasanth Kumar Padarthi @ 2026-05-12 17:50 UTC (permalink / raw)
  To: joel, andrew
  Cc: robh, krzk+dt, conor+dt, devicetree, linux-aspeed,
	linux-arm-kernel, Prasanth Kumar Padarthi

This series adds initial device tree support for the ASRock Rack
B650D4U BMC, which is based on the ASPEED AST2600 SoC.

The B650D4U is a server motherboard for AMD Ryzen processors. Hardware
details were extracted via reverse engineering of vendor firmware.

Hardware features included:
 - UART5 Console
 - MAC0 (RGMII) for dedicated management LAN
 - I2C7 for FRU EEPROM
 - FMC/SPI 64MB Flash layout

Validation:
Logic has been verified against the AST2600 v1.5 datasheet. The DTS 
successfully compiles and was tested using QEMU (ast2600-evb) to verify 
serial console output and board identification. 

QEMU Boot Log Snippet:
---
[    0.000000] OF: fdt: Machine model: ASRock Rack B650D4U BMC
[    1.085143] 1e784000.serial: ttyS4 at MMIO 0x1e784000 (irq = 31) is a 16550A
[    1.090566] printk: legacy console [ttyS4] enabled
---

Full logs and reverse-engineering data are maintained at:
https://github.com/prasanthp20/asrock-b650d4u-bmc-support/blob/main/qemu-boot.log

Prasanth Kumar Padarthi (2):
  dt-bindings: arm: aspeed: Add ASRock Rack B650D4U
  ARM: dts: aspeed: Add ASRock Rack B650D4U BMC

 .../bindings/arm/aspeed/aspeed.yaml           |  1 +
 arch/arm/boot/dts/aspeed/Makefile             |  1 +
 .../dts/aspeed/aspeed-bmc-asrock-b650d4u.dts  | 61 +++++++++++++++++++
 3 files changed, 63 insertions(+)
 create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-b650d4u.dts

-- 
2.47.3



^ 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