[PATCH v5 1/1] pinctrl: mediatek: Add EINT support for multiple addresses

Uwe Kleine-König u.kleine-koenig at baylibre.com
Mon Apr 14 07:57:26 PDT 2025


Hello,

this patch became commit 3ef9f710efcb in v6.15-rc1. It breaks booting a
mt8365-evk.

With earlycon it's possible to see a null pointer exception:

	[    0.072938] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000002
	[    0.074101] Mem abort info:
	[    0.074468]   ESR = 0x0000000096000004
	[    0.074984]   EC = 0x25: DABT (current EL), IL = 32 bits
	[    0.075681]   SET = 0, FnV = 0
	[    0.076083]   EA = 0, S1PTW = 0
	[    0.076495]   FSC = 0x04: level 0 translation fault
	[    0.077134] Data abort info:
	[    0.077511]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
	[    0.078229]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
	[    0.078891]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
	[    0.079593] [0000000000000002] user address but active_mm is swapper
	[    0.080426] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
	[    0.081248] Modules linked in:
	[    0.081656] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.14.0-rc3-00113-g3ef9f710efcb #18
	[    0.082796] Hardware name: MediaTek MT8365 Open Platform EVK (DT)
	[    0.083594] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
	[    0.084507] pc : mtk_eint_do_init+0x470/0x580
	[    0.085088] lr : mtk_eint_do_init+0x37c/0x580
	[    0.085663] sp : ffff80008160b7e0
	[    0.086098] x29: ffff80008160b850 x28: 0000000000000000 x27: ffff8000812600b0
	[    0.087040] x26: ffff0000bf9b7a80 x25: ffff0000bf9baac8 x24: ffff0000bf9baac8
	[    0.087981] x23: 0000000000000000 x22: ffff8000800cebe0 x21: ffff80008147e418
	[    0.088922] x20: 0000000000000000 x19: ffff0000021be780 x18: 00000000ffffffff
	[    0.089863] x17: 0000000000000003 x16: ffff000001832b00 x15: ffff0000021b70e0
	[    0.090804] x14: 0000000000000001 x13: ffff0000021b70e3 x12: ffff000001832c00
	[    0.091744] x11: 0000000000000000 x10: ffff800080f11cc0 x9 : ffff80008160b780
	[    0.092685] x8 : ffff80008160b780 x7 : 0000000000000000 x6 : 00000000ffffffff
	[    0.093626] x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff800080d0dbb0
	[    0.094567] x2 : 0000000000000000 x1 : ffff800080d53100 x0 : 0000000000000000
	[    0.095509] Call trace:
	[    0.095831]  mtk_eint_do_init+0x470/0x580 (P)
	[    0.096408]  mtk_pctrl_init+0x464/0x4fc
	[    0.096917]  mtk_pctrl_common_probe+0x30/0x60
	[    0.097494]  platform_probe+0x68/0xdc
	[    0.097981]  really_probe+0xbc/0x2c0
	[    0.098457]  __driver_probe_device+0xcc/0x120
	[    0.099035]  driver_probe_device+0x3c/0x154
	[    0.099590]  __device_attach_driver+0xb8/0x140
	[    0.100179]  bus_for_each_drv+0x88/0xe8
	[    0.100688]  __device_attach+0xa0/0x190
	[    0.101197]  device_initial_probe+0x14/0x20
	[    0.101752]  bus_probe_device+0xb4/0xc0
	[    0.102261]  device_add+0x554/0x72c
	[    0.102724]  of_device_add+0x54/0x64
	[    0.103201]  of_platform_device_create_pdata+0x8c/0x118
	[    0.103891]  of_platform_bus_create+0x190/0x38c
	[    0.104491]  of_platform_bus_create+0x1d8/0x38c
	[    0.105091]  of_platform_populate+0x74/0x108
	[    0.105656]  of_platform_default_populate_init+0xe8/0x10c
	[    0.106369]  do_one_initcall+0x60/0x1d4
	[    0.106879]  kernel_init_freeable+0x210/0x274
	[    0.107456]  kernel_init+0x20/0x140
	[    0.107921]  ret_from_fork+0x10/0x20
	[    0.108400] Code: 14000002 39404265 f9403260 8b170000 (39400802)
	[    0.109199] ---[ end trace 0000000000000000 ]---
	[    0.109821] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
	[    0.110824] SMP: stopping secondary CPUs
	[    0.111345] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---

The problem is that ...

On Sat, Mar 22, 2025 at 11:52:28AM +0800, Hao Chang wrote:
>  int mtk_eint_do_init(struct mtk_eint *eint)
>  {
> -	int i;
> +	unsigned int size, i, port, inst = 0;
> +	struct mtk_pinctrl *hw = (struct mtk_pinctrl *)eint->pctl;
>  
>  	/* If clients don't assign a specific regs, let's use generic one */
>  	if (!eint->regs)
>  		eint->regs = &mtk_generic_eint_regs;
>  
> -	eint->wake_mask = devm_kcalloc(eint->dev, eint->hw->ports,
> -				       sizeof(*eint->wake_mask), GFP_KERNEL);
> -	if (!eint->wake_mask)
> +	eint->base_pin_num = devm_kmalloc_array(eint->dev, eint->nbase, sizeof(u16),
> +						GFP_KERNEL | __GFP_ZERO);
> +	if (!eint->base_pin_num)
>  		return -ENOMEM;
>  
> -	eint->cur_mask = devm_kcalloc(eint->dev, eint->hw->ports,
> -				      sizeof(*eint->cur_mask), GFP_KERNEL);
> -	if (!eint->cur_mask)
> -		return -ENOMEM;
> +	if (eint->nbase == 1) {
> +		size = eint->hw->ap_num * sizeof(struct mtk_eint_pin);
> +		eint->pins = devm_kmalloc(eint->dev, size, GFP_KERNEL);
> +		if (!eint->pins)
> +			goto err_pins;
> +
> +		eint->base_pin_num[inst] = eint->hw->ap_num;
> +		for (i = 0; i < eint->hw->ap_num; i++) {
> +			eint->pins[i].instance = inst;
> +			eint->pins[i].index = i;
> +			eint->pins[i].debounce = (i < eint->hw->db_cnt) ? 1 : 0;
> +		}
> +	}
>  
> -	eint->dual_edge = devm_kcalloc(eint->dev, eint->hw->ap_num,
> -				       sizeof(int), GFP_KERNEL);
> -	if (!eint->dual_edge)
> -		return -ENOMEM;
> +	if (hw && hw->soc && hw->soc->eint_pin) {
> +		eint->pins = hw->soc->eint_pin;
> +		for (i = 0; i < eint->hw->ap_num; i++) {
> +			inst = eint->pins[i].instance;
> +			if (inst >= eint->nbase)
> +				continue;
> +			eint->base_pin_num[inst]++;
> +		}
> +	}
> +
> +	eint->pin_list = devm_kmalloc(eint->dev, eint->nbase * sizeof(u16 *), GFP_KERNEL);
> +	if (!eint->pin_list)
> +		goto err_pin_list;
> +
> +	eint->wake_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL);
> +	if (!eint->wake_mask)
> +		goto err_wake_mask;
> +
> +	eint->cur_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL);
> +	if (!eint->cur_mask)
> +		goto err_cur_mask;
> +
> +	for (i = 0; i < eint->nbase; i++) {
> +		eint->pin_list[i] = devm_kzalloc(eint->dev, eint->base_pin_num[i] * sizeof(u16),
> +						 GFP_KERNEL);
> +		port = DIV_ROUND_UP(eint->base_pin_num[i], 32);
> +		eint->wake_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL);
> +		eint->cur_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL);
> +		if (!eint->pin_list[i] || !eint->wake_mask[i] || !eint->cur_mask[i])
> +			goto err_eint;
> +	}
>  
>  	eint->domain = irq_domain_add_linear(eint->dev->of_node,
>  					     eint->hw->ap_num,
>  					     &irq_domain_simple_ops, NULL);
>  	if (!eint->domain)
> -		return -ENOMEM;
> +		goto err_eint;
>  
>  	if (eint->hw->db_time) {
>  		for (i = 0; i < MTK_EINT_DBNC_MAX; i++)
> @@ -523,8 +580,11 @@ int mtk_eint_do_init(struct mtk_eint *eint)
>  
>  	mtk_eint_hw_init(eint);
>  	for (i = 0; i < eint->hw->ap_num; i++) {
> +		inst = eint->pins[i].instance;

... here eint->pins is NULL.

> +		if (inst >= eint->nbase)
> +			continue;
> +		eint->pin_list[inst][eint->pins[i].index] = i;
>  		int virq = irq_create_mapping(eint->domain, i);
> -
>  		irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
>  					 handle_level_irq);
>  		irq_set_chip_data(virq, eint);
> @@ -534,6 +594,27 @@ int mtk_eint_do_init(struct mtk_eint *eint)
>  					 eint);
>  
>  	return 0;
> +
> +err_eint:
> +	for (i = 0; i < eint->nbase; i++) {
> +		if (eint->cur_mask[i])
> +			devm_kfree(eint->dev, eint->cur_mask[i]);
> +		if (eint->wake_mask[i])
> +			devm_kfree(eint->dev, eint->wake_mask[i]);
> +		if (eint->pin_list[i])
> +			devm_kfree(eint->dev, eint->pin_list[i]);
> +	}
> +	devm_kfree(eint->dev, eint->cur_mask);
> +err_cur_mask:
> +	devm_kfree(eint->dev, eint->wake_mask);
> +err_wake_mask:
> +	devm_kfree(eint->dev, eint->pin_list);
> +err_pin_list:
> +	if (eint->nbase == 1)
> +		devm_kfree(eint->dev, eint->pins);
> +err_pins:
> +	devm_kfree(eint->dev, eint->base_pin_num);
> +	return -ENOMEM;
>  }
>  EXPORT_SYMBOL_GPL(mtk_eint_do_init);

That commit can be cleanly reverted on top of v6.15-rc2 which makes my
machine boot again.

Best regards
Uwe

#regzbot introduced: 3ef9f710efcb
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mediatek/attachments/20250414/e2fb9951/attachment-0001.sig>


More information about the Linux-mediatek mailing list